How to Use Room Database: A Step-by-Step Guide

First of all, Room is not a database; the actual database here is SQLite. Room is a library in the Jetpack Framework that simplifies tasks and acts as a bridge between SQLite and your code.

Why Do We Use ROOM Database?

  1. The annotations are simple, reducing boilerplate code.

  2. In an online app, we can easily cache relevant data so that we can display it even when the user is offline.

First, we need to add the dependencies:

dependencies {
    val room_version = "2.6.1"

    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor("androidx.room:room-compiler:$room_version")

    // To use Kotlin annotation processing tool (kapt)
    kapt("androidx.room:room-compiler:$room_version")
}

and you need to apply a plugin for KAPT , if you aren’t familiar about KAPT then checkout “What is KAPT & KSP ?“

plugins {
    id("kotlin-kapt")
}
  • Folder Structure :

Now let's break down our folder structure. It will look like this:

In the data layer, I have added three packages: dao, database, and tables. These are all we need to use ROOM

  • Tables :

In the tables, we create data classes or entities using the @Entity annotation. Here, I am creating a contact database, for example, where the main parameters will be name and phoneNumber. We can create multiple tables here.

@Entity(tableName = "contacts")
data class Contact(
    @PrimaryKey(autoGenerate = true) val id: Int? = null,
    val name: String,
    val phoneNumber: String,
)
  • Database :

  1. Database

    The database is simply a collection of tables that store records.

    To declare a database, we need to annotate it with @Database.

     @Database(entities = [Contact::class], version = 1)
     abstract class ContactDatabase : RoomDatabase() {
         abstract fun dao(): ContactDao
     }
    
  1. Database Instance

    We need to create an instance of the database. Later, we can improve this approach using "Dependency Injection." You can learn more by checking out "What is dependency injection?" However, for now, we won't be using that method.

     object DatabaseInstance {
         fun getDB(context: Context): ContactDatabase {
             return Room.databaseBuilder(context,ContactDatabase::class.java,"contact.db").allowMainThreadQueries().build()
         }
     }
    

DAO (Data Access Objects):

A DAO is an interface where all the abstract functions are defined:

@Dao
interface ContactDao {

    @Upsert
    fun insertContact(contact: Contact)

    @Delete
    fun deleteContact(contact: Contact)

    @Query("SELECT * FROM contacts ORDER BY name ASC")
    fun getContactsOrderedbyFirstName(): List<Contact>

    @Query("SELECT * FROM contacts ORDER BY phoneNumber ASC")
    fun getContactsOrderedbyPhoneNo(): List<Contact>

}

After completing all this, we're ready to go. Feel free to share your insights in the comments.

0
Subscribe to my newsletter

Read articles from Sagnik Mukherjee directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sagnik Mukherjee
Sagnik Mukherjee

Native Android Developer and content creator