Day 19: CRUD Operations with Room – Practical Database Usage in Android

🧠 Full Blog Post:

In modern Android development, storing structured data locally is crucial for offline support, caching, and smooth user experience. Room, a part of Jetpack Architecture Components, makes it easy to interact with SQLite databases using clean and maintainable Kotlin code. One of the most essential concepts you’ll use with Room is CRUD operations: Create, Read, Update, and Delete.

In this Day 19 guide, we explore practical CRUD usage with Room and build a simple example to understand how Room fits into real-world Android apps using MVVM and Kotlin Coroutines.


📦 What is CRUD?

CRUD stands for:

  • Create → Insert new records into the database
  • Read → Fetch data (e.g., list of items)
  • Update → Modify existing data
  • Delete → Remove data from the database

🏗️ Setting Up Room

Before using Room, add the dependencies in your build.gradle:

kotlinCopyEditdependencies {
    def room_version = "2.6.1"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
}

Enable Kotlin annotation processing:

kotlinCopyEditapply plugin: 'kotlin-kapt'

🧱 Step-by-Step Practical Setup

1️⃣ Define the Entity

kotlinCopyEdit@Entity(tableName = "user_table")
data class User(
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    val name: String,
    val email: String
)

2️⃣ Create the DAO

kotlinCopyEdit@Dao
interface UserDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUser(user: User)

    @Query("SELECT * FROM user_table ORDER BY id DESC")
    fun getAllUsers(): Flow<List<User>>

    @Update
    suspend fun updateUser(user: User)

    @Delete
    suspend fun deleteUser(user: User)
}

3️⃣ Setup the Room Database

kotlinCopyEdit@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Use a singleton to instantiate the database:

kotlinCopyEditobject DatabaseProvider {
    private var INSTANCE: AppDatabase? = null

    fun getDatabase(context: Context): AppDatabase {
        return INSTANCE ?: synchronized(this) {
            val instance = Room.databaseBuilder(
                context,
                AppDatabase::class.java,
                "app_database"
            ).build()
            INSTANCE = instance
            instance
        }
    }
}

💡 Practical Example: ViewModel Usage

kotlinCopyEdit@HiltViewModel
class UserViewModel @Inject constructor(private val dao: UserDao) : ViewModel() {

    val users: StateFlow<List<User>> = dao.getAllUsers()
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())

    fun addUser(name: String, email: String) = viewModelScope.launch {
        dao.insertUser(User(name = name, email = email))
    }

    fun deleteUser(user: User) = viewModelScope.launch {
        dao.deleteUser(user)
    }
}

🚀 Best Practices for Room CRUD

  • Use Flow or LiveData for real-time updates in UI
  • Handle nulls and empty lists gracefully
  • Use OnConflictStrategy.REPLACE to avoid duplicates
  • Perform database operations on background threads with Coroutines

CRUD Operations with Room diagram

🔹 Key Points:

  • What CRUD means in Room
  • Setting up Room components (Entity, DAO, Database)
  • Real-world usage examples of CRUD
  • Kotlin Coroutines and LiveData/StateFlow usage
  • Best practices for scalable database code

🎯 Conclusion

CRUD operations form the backbone of any local database interaction. With Room, Android developers can write simple, readable, and reliable code for managing app data. Whether it’s saving user profiles, todo tasks, or notes, Room combined with MVVM and Kotlin makes database operations efficient and scalable.


📚 Internal Links:

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top