Data Persistence with ROOM

The Room persistence library provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite.

The library helps you create a cache of your app’s data on a device that’s running your app. This cache, which serves as your app’s single source of truth, allows users to view a consistent copy of key information within your app, regardless of whether users have an internet connection.

In this shot, we will be learning how to set up ROOM in an Android Application.

Step 1: Add dependencies.

dependencies {
  def room_version = "2.2.5"

  implementation "androidx.room:room-runtime:$room_version"
  kapt "androidx.room:room-compiler:$room_version"

  // optional - Kotlin Extensions and Coroutines support for Room
  implementation "androidx.room:room-ktx:$room_version"

  // optional - Test helpers
  testImplementation "androidx.room:room-testing:$room_version"
}

Step 2: Create a Kotlin class, Employee.kt.

@Entity(tableName = "employee_database_table")
data class Employee(

        @PrimaryKey(autoGenerate = true)
        var employeeId: Long?,

        @ColumnInfo(name = "First_Name")
        var firstName: String?,

        @ColumnInfo(name = "Last_Name")
        var lastName: String?,

        @ColumnInfo(name = "Age")
        var age: Int?
)

@Entity - Describes the database object.

@PrimaryKey - Declares a unique ID. autoGenerate helps us to automatically generate unique keys.

@Column Info - Declares the columns for our table and their names.

Step 3: Create a DAO Kotlin class, EmployeeDatabaseDao.kt.

Data Access Objects (DAO) are the main classes where you define your database interactions. They can include a variety of query methods.

@Dao
interface EmployeeDatabaseDao{
    @Insert
    fun insert(employee: Employee)

    @Update
    fun update(employee: Employee)

    @Query("SELECT *  from employee_database_table WHERE employeeId = :key")
    fun get(key: Long): Employee?

    @Query("DELETE FROM employee_database_table")
    fun clear()

    @Query("SELECT * FROM employee_database_table ORDER BY employeeId DESC")
    fun getAllEmployees() : LiveData<List<Employee>>

    @Query("SELECT * FROM employee_database_table ORDER BY employeeId DESC LIMIT 1")
    fun getLastEmployee(): Employee?
}

The @Dao class illustrates various operations we could carry out on our database.

Step 4: Create a kotlin database class, EmployeeDatabase.kt.

@Database(entities = [Employee::class], version = 1, exportSchema = false)
abstract class EmployeeDatabase: RoomDatabase(){

    abstract val employeeDatabaseDao: EmployeeDatabaseDao

    companion object{

        @Volatile
        private var INSTANCE: EmployeeDatabase? = null

        fun getInstance(context: Context) : EmployeeDatabase{
            synchronized(this){
                var instance = INSTANCE

                if(instance == null){
                    instance = Room.databaseBuilder(
                            context.applicationContext,
                            EmployeeDatabase::class.java,
                            "employee_details_database"
                    ).fallbackToDestructiveMigration() .build()

                    INSTANCE = instance
                }
                return instance
            }
        }
    }
}

exportSchema allows us to export database information into a file.

companionObject allows access to the DAO methods without instantiating the class.

INSTANCE enables us to always reference the database and to avoid opening and closing connections that could be expensive.

@Volatile helps us make sure the value of INSTANCE is always up to date and the same to all execution threads.

synchronized block makes sure that only a single thread can access the database.

.fallbackToDestructiveMigration() enables conversion of rows from an old schema to a new schema.

Conclusion: This is a very basic implementation of ROOM on a simple Android Application.

Free Resources