Room Database with Kotlin Coroutines in Android

Room Database with Kotlin Coroutines in Android

In this tutorial, we are going to learn how to use Room Database with Kotlin Coroutines. We will learn to write the code inside the ViewModel with Kotlin Coroutines that follows a basic MVVM Architecture.

I will be using this project for the implementation part. If you have not gone through the project, you should go through and then come back. The project follows a basic MVVM Architecture for simplicity. You can find the complete code for the implementation mentioned in this blog in the project itself.

First, we need to set up our dependencies for the Room Database like below:

implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
implementation "androidx.room:room-ktx:2.2.5"

Do not forget to add the Kotlin plugin for Annotation Processing in your app-level gradle file.

apply plugin: 'kotlin-kapt'

Now, create the entity which will be our data class required for Room Database, for example, User.

@Entity
data class User(
    @PrimaryKey val id: Int,
    @ColumnInfo(name = "name") val name: String?,
    @ColumnInfo(name = "email") val email: String?,
    @ColumnInfo(name = "avatar") val avatar: String?
)

For this User, we need to create Dao required for Room Database, which we will name as UserDao.

@Dao
interface UserDao {

    @Query("SELECT * FROM user")
    suspend fun getAll(): List<User>

    @Insert
    suspend fun insertAll(users: List<User>)

    @Delete
    suspend fun delete(user: User)

}

Note: We have used suspend keyword to support Coroutines so that we can call it from a Coroutine or another suspend function.

Now, we need to create the AppDatabase which will extend RoomDatabase.

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {

    abstract fun userDao(): UserDao

}

After this, we will be needing a DatabaseBuilder which will be a Singleton.

object DatabaseBuilder {

    private var INSTANCE: AppDatabase? = null

    fun getInstance(context: Context): AppDatabase {
        if (INSTANCE == null) {
            synchronized(AppDatabase::class) {
                INSTANCE = buildRoomDB(context)
            }
        }
        return INSTANCE!!
    }

    private fun buildRoomDB(context: Context) =
        Room.databaseBuilder(
            context.applicationContext,
            AppDatabase::class.java,
            "mindorks-example-coroutines"
        ).build()

}

Then, we will create a DatabaseHelper interface.

interface DatabaseHelper {

    suspend fun getUsers(): List<User>

    suspend fun insertAll(users: List<User>)

}

Then, we will create a DatabaseHelperImpl which will implement the DatabaseHelper.

class DatabaseHelperImpl(private val appDatabase: AppDatabase) : DatabaseHelper {

    override suspend fun getUsers(): List<User> = appDatabase.userDao().getAll()

    override suspend fun insertAll(users: List<User>) = appDatabase.userDao().insertAll(users)

}

Note: Again, we have used the suspend so that we can call it from a coroutine or another suspend function.

Then, we can create the instance of DatabaseHelper like below:

val dbHelper = DatabaseHelperImpl(DatabaseBuilder.getInstance(applicationContext))

We can pass this instance wherever required, for example to the ViewModel and make the query to get the users from the database like below:

class RoomDBViewModel(private val apiHelper: ApiHelper, private val dbHelper: DatabaseHelper) :
    ViewModel() {
    
    init {
        fetchUsers()
    }

    private fun fetchUsers() {
        viewModelScope.launch {
            try {
                val usersFromDb = dbHelper.getUsers()

                // here you have your usersFromDb

            } catch (e: Exception) {
                // handler error
            }
        }
    }

}

This way, we are able to query the database using Kotlin Coroutines.

You can find the end to end implementation in this project.

That's it for now.

Learn System Design for your next Interview from here.

Also, Let’s become friends on Twitter, Linkedin, Github, Quora, and Facebook.