Local Database

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.

dependencies {
    implementation("androidx.room:room-runtime:2.6.1")
    implementation("androidx.room:room-ktx:2.6.1")
    kapt("androidx.room:room-compiler:2.6.1")
}

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.

Last updated