Android Room Persistence Library Sqlite Mapper with Kotlin

Sharing is caring!

In this tutorial, we will learn step by step to use the Android Room a persistence SQLite ORM mapper. As we have already practiced in my last tutorial with GreenDAO which is SQLite wrapper for fast ORM. I would be recommended to checking this post Exploring GreenDAO ORM database with Reactive RxJava.

Google I/O 2017 has introduced the new database persistence library called Room as ORM like GreenDAO and ORMLite. There are 3 major components in Room.

  1. Database
  2. Entity
  3. DAO

Database: Database is a component that creates the database holder. The annotation defines the list of entities, and the class’s content defines the list of data access objects (DAOs) in the database. It is also the main access point for the underlying connection.

Entity: This component represents a class that holds a database row. For each entity, a database table is created to hold the items.

DAO: This component represents a class or interfaces as a Data Access Object (DAO). DAOs are the main component of Room and are responsible for defining the methods that access the database.

For more detail Please check the official documentation.

I had been using Kotlin prior to the I/O announcement. Having google fully commit it to as a first-class citizen on Android was very encouraging. Here is the recommended post to check Kotlin.

Ok, Let’s integrate the Room library in one of the sample projects with Kotlin in reactive nature by RxJava2. The very first thing we need to add relevant dependencies in the build.gradle file.

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    ........................
    buildTypes {
       ...................
    }
}

dependencies {
    .................
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    compile 'android.arch.persistence.room:runtime:' + rootProject.archRoomVersion
    compile 'android.arch.persistence.room:rxjava2:' + rootProject.archRoomVersion
    kapt 'android.arch.persistence.room:compiler:' + rootProject.archRoomVersion
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
}
repositories {
    mavenCentral()
}

In the project level of build.gradle file we need to add maven google path to download the dependency.

buildscript {
    ext.kotlin_version = '1.1.4-3'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        maven { url "https://maven.google.com" }  // Do not forget to add this line
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    buildToolsVersion = "26.0.0"
    supportLibVersion = "26.0.0"
    archRoomVersion = "1.0.0-alpha9"
}

Now, all set up is ready, let’s create the database entity.

@Entity(tableName = "friends")
data class Friends (
        @PrimaryKey var friend_id: String?,
        var name: String?,
        var email: String?) {
}

Now let’s create a DAO class.

@Dao
interface FriendsSource {

    @Query("SELECT * FROM friends")
    fun loadAllFriends(): Flowable<List<Friends>>

    @Query("SELECT * FROM friends WHERE friend_id = :friend_id")
    fun loadFriend(friend_id: String?): Flowable<List<Friends>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(products: MutableList<Friends>) : Unit

    @Query("SELECT COUNT(*) from friends")
    fun countFriends(): Int
}

Now create an instance of a database.

@Database(entities = arrayOf(Friends::class), version = 1)
abstract class FriendsDatabase : RoomDatabase() {
    abstract fun friendsDao(): FriendsSource
   
    companion object {
        const val DATABASE_NAME = "friends-db"
    }
}

Now let’s create the instance of the database to observing with Live data.

object DatabaseCreator {

    val isDatabaseCreated = MutableLiveData<Boolean>()

    lateinit var database: FriendsDatabase

    private val mInitializing = AtomicBoolean(true)

    fun createDb(context: Context) {
        if (mInitializing.compareAndSet(true, false).not()) {
            return
        }

        isDatabaseCreated.value = false

        Completable.fromAction {
            database = Room.databaseBuilder(context, FriendsDatabase::class.java, FriendsDatabase.DATABASE_NAME).build()
        }
                .subscribeOn(Schedulers.computation())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ isDatabaseCreated.value = true }, {it.printStackTrace()})
    }

}

Let’s create an interface for what are the operations required in the project and implement those locally.

interface FriendsDataSource {

    fun getFriends(): Single<List<Friends>>

    fun saveFriends(list: List<Friends>) : Unit = Unit

    fun getCount(): Int
}

Ok, Let’s implement those.

object FriendsLocalSource : FriendsDataSource {
   
   val friendsDao = DatabaseCreator.database.friendsDao()

   override fun getCount(): Int {
        return friendsDao.countFriends()
    }

    override fun getFriends(): Single<List<Friends>> {
        return friendsDao.loadAllFriends()
                .firstOrError()
                .doOnSuccess {
                    if (it.isEmpty()) throw Exception()
                }
    }

    override fun saveFriends(list: List<Friends>) {
        friendsDao.insertAll(list.toMutableList())
    }
}

Please add database creator into MainApplication.

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        DatabaseCreator.createDb(this)
    }
}

Ok all done, We can call the insert operation to insert data into the table and get details from the database table.

  fun saveFriendsIntoDb(list: List<FriendsApiModel>){
        var listFriends = ArrayList<Friends>()
        for (FriendsApiModel in list) {
            var listUsers = FriendsApiModel!!.user;
            listUsers?.let {
                for (users in it) {
                    listFriends.add(Friends(users.id, users.name, users.email))
                }
            }
           }
         FriendsLocalSource.saveFriends(listFriends)
        }
  disposable = FriendsLocalSource
                            .getFriends()
                            .subscribe { data, error -> this@FriendsLiveData.value = Pair(data, error)}

Wrapping Up:  This is the good implementation of Android Room with Kotlin. Room introduced in new Android Architecture component. But this is still in alpha, So it might change implementation. If you wondering Kotlin for android then I would be recommended to check all this post of Kotlin Category. You can get the full source code from Github.

Please do subscribe your email to get every newsletter from this blog and if you feel that this post helps you then do not forget to share and comment below.

Happy coding 🙂

0 0 votes
Article Rating
Android Room Persistence Library Sqlite Mapper with Kotlin
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Scroll to top
0
Would love your thoughts, please comment.x
()
x