Room Database Android Example [Beginners]

Room Database is a part of the Android Architecture components which provides an abstraction layer over SQLite which allows for more robust database access while still providing the full power of SQLite. Room is a persistence library, part of the Android Jetpack.

Why use Room Database?

  • Compile-time verification of SQL queries. each @Query and @Entity is checked at the compile time.
  • Using Annotations to reduce the boilerplate code.
  • Easily integrated with other Architecture components like LiveData, RxJava.

What is the difference between room and sqlite database ?

  • In case of SQLite, There is no compile time verification of raw SQLite queries. But in Room there is SQL validation at compile time.
  • As your schema changes, you need to update the affected SQL queries manually. Room solves this problem.
  • You need to use lots of boilerplate code to convert between SQL queries and Java data objects. But, Room maps our database objects to Java Object without boilerplate code.
  • Room is built to work with LiveData and RxJava for data observation, while SQLite does not.
Room architecture looks like the following:
Room database architecture

There Are Basically 3 Major Components In Room.

1. @Entity

Entity Representation of table and columns become very easy. you have to annotate @Entity to a class and name of the class becomes table name and, data members becomes the name of the columns. “@Entity” class represent an entity in a table.
@Entity(tableName = "user")
data class Users(@PrimaryKey(autoGenerate = true)var userId: Int? = null,
                 val userName: String, var location: String, val email: String)

2. @Dao— Data Access Object

An Interface where we put all our SQL queries. We don’t require to write whole queries now; we need to make a method and annotate with specific annotations like @Insert - Used to insert record into Room database. @Delete - Used to delete record from Room database. @Update - Used to update record in Room Database. @Query - Used to enter the Query like (SELECT FROM*)
@Dao
interface UserDao {

    @Insert
    fun insertUser(users: Users)

    @Query("Select * from user")
    fun gelAllUsers(): List<Users>

    @Update
    fun updateUser(users: Users)

    @Delete
    fun deleteUser(users: Users)

}

3. @Database

This is an abstract class that extends RoomDatabase, this is where you define the entities (tables)and the version number of your database. It contains the database holder and serves as the main access point for the underlying connection.
@Database(entities = [Users::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {

    abstract fun userDao() : UserDao
}
Done with explanation. Lets start the implementation part. I am going to create a sample app for user management using the room database in kotlin. In the app, I have added functionalities to insert, delete, update and list all the users.

Step 1 - Add dependencies

First, We need to add dependencies for room database in our build.gradle file. 

Step 2: Create a Model Class

Room creates a table for each class annotated with @Entity.
  • Annotate the class with @Entity and use the tableName property to set the name of the table.
  • Set the primary key by adding the @PrimaryKey annotation to the correct fields — in our case, this is the ID of the User.
  • Set the name of the columns for the class fields using the @ColumnInfo(name = “column_name”) annotation. Feel free to skip this step if your fields already have the correct column name.
  • If multiple constructors are suitable, add the @Ignore annotation to tell Room which should be used and which not.
@Entity(tableName = "user")
data class Users(@PrimaryKey(autoGenerate = true)var userId: Int? = null,
                 val userName: String, var location: String, val email: String)

Step 3 - Create DAO (Data Access Objects)

DAOs are responsible for defining the methods that access the database.
@Dao
interface UserDao {

    @Insert
    fun insertUser(users: Users)

    @Query("Select * from user")
    fun gelAllUsers(): List<Users>

    @Update
    fun updateUser(users: Users)

    @Delete
    fun deleteUser(users: Users)

}
Here we just define basic SQL database functionality like inserting and deleting entries. You can see that the @Query annotation is used to annotate functions which are using queries. You can also use parameters in your queries using :parametername .

Type Converters

Type Converters are used when we declare a property which Room and SQL don’t know how to serialize. Let’s see an example of how to serialize List<String> data type.
class Converters {

    @TypeConverter
    fun fromString(value: String): List<String> {
        val listType = object : TypeToken<List<String>>() {

        }.type
        return Gson().fromJson(value, listType)
    }

    @TypeConverter
    fun fromArrayList(list: List<String>): String {
        val gson = Gson()
        return gson.toJson(list)
    }
}

Step 4 — Create the database

Now, Everything is ready to create Database. We can create Room Database by extend the RoomDatabase. AppDatabase.kt
@Database(entities = [Users::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {

    abstract fun userDao() : UserDao

    companion object {
        private var INSTANCE: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase? {
            if (INSTANCE == null) {
                synchronized(AppDatabase::class) {
                    INSTANCE = Room.databaseBuilder(context.applicationContext,
                        AppDatabase::class.java, "user.db").allowMainThreadQueries()
                        .build()
                }
            }
            return INSTANCE
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}
Things to notice here:
  • This is an abstract class that has to extend from RoomDatabase.
  • It has to be annotated with @Database, it receives a list of entities with all the classes that compose the database (all these classes have to be annotated with @Entity). We also have to provide a database version.
  • We have to declare an abstract function for each of the entities included in the @Database annotation, this function has to return the correspondentDAO (A class annotated with @Dao).
  • Finally, we declare a companion object to get static access to the method getAppDataBase which gives us a singleton instance of the database.

  Step 5 - CRUD operation on Room Database

Now the room database is ready for the CRUD operation. UserRepository.kt
class UserRepository(context: Context) {

    var db: UserDao = AppDatabase.getInstance(context)?.userDao()!!


    //Fetch All the Users
    fun getAllUsers(): List<Users> {
        return db.gelAllUsers()
    }

    // Insert new user
    fun insertUser(users: Users) {
        insertAsyncTask(db).execute(users)
    }

    // update user
    fun updateUser(users: Users) {
        db.updateUser(users)
    }

    // Delete user
    fun deleteUser(users: Users) {
        db.deleteUser(users)
    }

    private class insertAsyncTask internal constructor(private val usersDao: UserDao) :
        AsyncTask<Users, Void, Void>() {

        override fun doInBackground(vararg params: Users): Void? {
            usersDao.insertUser(params[0])
            return null
        }
    }
}
If you try running the above code with the created database above, your app will crash as the operation performed is on the main thread. By default, Room keeps a check of that and doesn’t allow operations on the main thread as it can makes your UI Not responding. You can avoid that by using AsyncTask or Handler or Rxjava with IO schedulers or any other options which puts the operation on any other thread. There is one more option, which allows you to do the operation on the main thread. You can use the same for testing but should avoid. To do that you can add allowMainThreadQueries() on the builder. Result of my room database android example. Also, You can download the example in github. Conclusion Thanks for reading. Please try room database in android with different query to practice. And let me know your feedback in comments.

One Reply to “Room Database Android Example [Beginners]”

Leave a Reply

Your email address will not be published. Required fields are marked *