Android Development

Google's android guide Home Contact

Room Database library for Android

Room provides an alternate option instead of using SQLite datbases directly in Android.

Some of the key features include:

  • Abstraction Over SQLite: Room provides a higher-level abstraction over SQLite, which reduces the amount of boilerplate code required to create and manage a database.
  • Type-Safe Queries: Room uses compile-time checks for SQL queries, catching errors early in the development process and reducing runtime errors related to database operations.
  • Integration with LiveData: Room integration with Android's LiveData and RxJava, allows to observe changes in the database and automatically update the UI when data changes.
  • Easy Migration: Room simplifies and allows making changes to the database schema without loosing existing data.
  • Less boilerplate code: Room maps database objects to Java object with much less boilerplate code.
  • Annotation-Based: Room uses annotations to define the database schema, making it easy to define and maintain the data model.

Major Room Components (@Entity, @Database, @Dao)

Entity (table within database): Entity is a modal class, annotated with @Entity. Variables (data members) of this class represent columns and the class itself is table. The class contains no logic. It allows to define columns, primary keys, and other table-related properties. It defines the data structure for corresponding table, allows for automatic table creation, and ensures type safety when working with the database.

When a class is annotated with @Entity, it tells Room to treat instances of that class as rows in a database table. Each field (property) in the annotated class corresponds to a column in the database table. For example:


@Entity(tableName = "employees")
data class EmployeesEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,
    val name: String,
    val position: String,
    val salary: Double
)

Here the chosen field types and names for "employees" table corresponds to:
  • id: Auto-incremented primary key of type Long.
  • name: String field to store the employee's name.
  • position: String field to store the employee's job title.
  • salary: Double-precision floating-point field to store the employee's salary.
  • .

DAO: It is a Database access object (an interface class) responsible for defining methods to access the database. Different queries can be performed here by using corresponding annotations such as @Insert (insert records), @Delete (delete records), @Update (update records), @Query (various queries).

Define a DAO interface that will contain the methods for performing database operations on the above defined EmployeesEntity table. These methods include insert, update, delete, and query operations.

@Dao
interface EmployeesDao {
    @Insert
    suspend fun insertEmployee(employee: EmployeesEntity)

    @Update
    suspend fun updateEmployee(employee: EmployeesEntity)

    @Delete
    suspend fun deleteEmployee(employee: EmployeesEntity)

    @Query("SELECT * FROM employees")
    suspend fun getAllEmployees(): List
}
    

Database: It is an abstract class where all database entries are stored, called as Entities. @Database annotation is used to define a database class, which serves as the main access point to the SQLite database. This class is responsible for creating, opening, and managing the database instance. It also provides access to the Data Access Objects (DAOs) that allow to perform database operations.

Define a database class that extends RoomDatabase and annotate it with @Database. In the entities parameter, specify the entity class (in this case, EmployeesEntity), and set the version number.
@Database(entities = [EmployeesEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun employeesDao(): EmployeesDao

    companion object {
        private var instance: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, "app-database")
                .build()
        }
    }
}

  • @Database annotation specifies the entity class and database version.
  • employeesDao() provides access to the EmployeesDao interface.
  • companion object provides a singleton instance of the AppDatabase.

Summary Steps to use Room Database

  • Add Dependencies: Add the Room dependencies to the app's build.gradle file.
  • Define Entity Class: Create entity classes that represent the database tables. Annotate these classes with @Entity, and specify the table name and primary key.
  • Create Database: Create an abstract class that extends RoomDatabase and defines the database and its tables. Annotate this class with @Database and specify the list of entity classes.
  • Create Data Access Objects (DAOs): Create interfaces or abstract classes for data access objects (DAOs) and define methods for database operations, such as inserting, updating, deleting, and querying data. Annotate DAO methods with appropriate annotations (e.g., @Insert, @Delete, @Update, @Query).
  • Initialize Room Database: Obtain an instance of your Room database using a RoomDatabase.Builder and the build() method. Typically do this in an application class or in an activity's onCreate method.
    val database = AppDatabase.getInstance(applicationContext)
    
    
  • Perform Database Operations: Use the defined DAOs to perform database operations. Use database class AppDatabase for the created table, and use it to perform database operations using the defined DAO (EmployeesDao) in the Android application. Execute database operations on a background thread, and Room will automatically handle thread synchronization.