In Android development, Room is a persistence library that provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite. Room is part of the Android Jetpack suite and is designed to simplify database management and improve code readability.
Add Dependencies
First, include the necessary Room dependencies in your build.gradle or build.gradle.kts file.
Also, make sure you have the Kotlin annotation processing tool (kapt) plugin applied in your build.gradle or build.gradle.kts file.
// App level
plugins {
id("kotlin-kapt")
}
Define Your Data Entity
Create a data class representing a table in your database. Annotate the class with @Entity and its primary key with @PrimaryKey.
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.wahidabd.library.base.Model
@Entity(tableName = "note")
data class NoteEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
val id: Int? = null,
@ColumnInfo(name = "title")
val title: String,
@ColumnInfo(name = "description")
val description: String,
): Model()
Create a Data Access Obeject (DAO)
Define an interface annotated with @Dao that contains methods for accessing the database and implement OneLocalDb.
@Dao
abstract class NoteDao : OneLocalDb<NoteEntity, Int> {
@Query("SELECT * FROM note")
abstract override fun getList(): Flow<List<NoteEntity>>
@Query("SELECT * FROM note WHERE id = :id")
abstract override fun get(id: Int?): Flow<NoteEntity>
}
Create the Room Database
Define an abstract class that extends RoomDatabase and includes an abstract method to get an instance of your DAO.
@Database(entities = [NoteEntity::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun noteDao(): NoteDao
companion object{
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
if (INSTANCE == null){
INSTANCE = Room
.databaseBuilder(context.applicationContext, AppDatabase::class.java, "note.db")
.fallbackToDestructiveMigration()
.build()
}
return INSTANCE!!
}
fun destroyDatabase(){
INSTANCE = null
}
}
}
Implement the Function in Data Store
and you can use queries like save, update, delete etc. on the data store. For example
interface NoteRepository {
suspend fun save(data: NoteEntity)
suspend fun update(data: NoteEntity)
suspend fun get(id: Int): Flow<NoteEntity>
suspend fun getList(): Flow<List<NoteEntity>>
suspend fun remove(data: NoteEntity)
}
class NoteDataStore(private val db: NoteDao) : NoteRepository {
override suspend fun save(data: NoteEntity) {
db.save(data)
}
override suspend fun update(data: NoteEntity) {
db.update(data)
}
override suspend fun get(id: Int): Flow<NoteEntity> {
return db.get(id)
}
override suspend fun getList(): Flow<List<NoteEntity>> {
return db.getList()
}
override suspend fun remove(data: NoteEntity) {
db.remove(data)
}
}
You can see an example of using an activity or fragment here.