RoomDB
Dependencies
Section titled “Dependencies”ViewModel Required - add kapt plugin at plugins section
plugins { id("kotlin-kapt")}implementation("androidx.room:room-ktx:2.6.1")kapt("androidx.room:room-compiler:2.6.1")Schema (@Entity)
Section titled “Schema (@Entity)”@Entity(tableName = "user")data class User( @PrimaryKey(autoGenerate = true) val id: Int = 0, val name: String, // default column name will be "name" // Set some custom props with @ColumnInfo like custom ColumnName or DefaultValue @ColumnInfo(name = "user_name", defaultValue = "Unknown", collate = ColumnInfo.NOCASE) val name: String = "EliasChen", val age: Int, val hobby: String)To set the default value: val name: String = "EliasChen"
DB Actions (@Dao)
Section titled “DB Actions (@Dao)”@Daointerface UserDao { @Insert suspend fun insert(user: User)
@Query("SELECT * FROM user") suspend fun getAllUsers(): List<User>
// use flow to auto get updated data @Query("SELECT * FROM user") fun getAllUsers(): Flow<List<User>>
@Delete suspend fun delete(user: User)
@Query("DELETE FROM user") suspend fun deleteAll()
@Query("SELECT COUNT(*) FROM user WHERE name = :name") suspend fun checkNameExists(name: String): Int}Parse
fun’s data to@Queryby adding:at the start of the string. Ex::name
Database Entry Point (@Database)
Section titled “Database Entry Point (@Database)”@Database(entities = [<Schema-name>::class,<Schema-name>::class], version = 1)abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao}Build Database
Section titled “Build Database”Requires passing context from parent
fun getDatabase(context: Context): AppDatabase { return Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "app_database" ) .fallbackToDestructiveMigration() .build()}Use .fallbackToDestructiveMigration() to drop old schema when DB migrates
Delete the database file
Section titled “Delete the database file”context.deleteDatabase("db")ViewModel for Table
Section titled “ViewModel for Table”Via Flow (auto update)
Section titled “Via Flow (auto update)”class TodoViewModel(private val db: AppDB) : ViewModel() { val allTodo: Flow<List<Todo>> = db.todoDao().select()
fun insert(todo: Todo) = viewModelScope.launch { db.todoDao().insert(todo) }
fun deleteTodo(id: Int) = viewModelScope.launch { db.todoDao().delete(id) }
fun updateName(newName: String, id: Int) = viewModelScope.launch { db.todoDao().updateName(newName, id) }
fun updateDone(done: Boolean, id: Int) = viewModelScope.launch { db.todoDao().doneTodo(done, id) }}Via Manual Update
Section titled “Via Manual Update”class UserViewModel(private val database: AppDatabase) : ViewModel() { val users = mutableStateListOf<User>() // for storing data from DB
init { updateUsers() }
fun updateUsers() { viewModelScope.launch { users.clear() users.addAll(database.userDao().getAllUsers()) } }
fun addUser(name: String) { viewModelScope.launch { database.userDao().insert(User(name = name)) updateUsers() } }
fun deleteUser(user: User) { viewModelScope.launch { database.userDao().delete(user) updateUsers() } }
fun deleteAllUsers() { viewModelScope.launch { database.userDao().deleteAll() updateUsers() } }
suspend fun checkNameExists(name: String): Boolean { return database.userDao().checkNameExists(name) > 0 }}NOTE: All DB actions must be in a
suspend functionor aviewModelScope
Setup Context for Database
Section titled “Setup Context for Database”val database = getDatabase(this)val userViewModel = UserViewModel(database)Create database from MainActivity and pass database to the viewModel that interacts with the database