9. Persistence Data in Kotlin

Birat Rai
3 min readDec 23, 2017

--

Kotlin series has been developed keeping in mind, you are already familiar at least at beginner’s level.

This is the Ninth milestone towards our Kotlin series. Go to the Eighth Milestone if you haven’t done so

In this series, we will simply follow the coding challenges developed for the Android Developer Fundamentals Course, Unit 4— Lesson1.

This will contain the handling persistence data.

  1. Sqlite:
  2. Room:
Sqlite CRUD operations

How to handle persistence storage in Kotlin using sqlite?

  • We will be handling Sqlite with creating database, inserting, updating and querying through SQLiteOpenHelper.
  • Extending SQLiteOpenHelper is pretty much the same as in Java.
class WordListOpenHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION)
  • We can simply get an instance of the SqliteOpenHelper and access it’s method.
val wordItem: List<WordItem> = db!!.query() // Query database
val searchString = db?.search(searchText.toString())
// Search database
Room Architecture

How to start with Room in Kotlin?

  • Room is one of the Architecture component recently introduced which is an ORM library.
  • It provides an abstraction layer over SQLite to allow fluent database access.
  • Import Dependency. Apart from the room dependency we also need to import Kotlin annotation processor Kapt.
apply plugin: 'kotlin-kapt' // We need kapt plugin for the Kotlin annotation processor
kapt "android.arch.persistence.room:compiler:1.0.0" // Dependency for the the Kotlin-kapt
// Dependency for Room
implementation "android.arch.persistence.room:runtime:1.0.0"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0"
  • Creating Database Entity to define database schema.
// @Entity marks the class as an entity
@Entity(tableName = "room_word_list")
// table name for db, By default, Room uses the class name as the database table name
class RoomWordItem {
// @PrimaryKey should be used in at least one field
@PrimaryKey(
autoGenerate = true)
var id: Int = 0
// Room uses the field names as the column names in the database. If you want a column to have a different name, add the @ColumnInfo annotation to a field
@ColumnInfo(name = "word_column")
var word: String? = ""
}
  • Room DAO to handle the database queries.
@Dao
interface RoomWordDao {
// We can write sql queries directly
@Query("SELECT * FROM room_word_list")
val getAllFromDb() List<RoomWordItem>

@Query("SELECT * FROM room_word_list WHERE word_column LIKE :word")
fun findByWord(word: String): RoomWordItem

@Insert
fun insertAll(words: ArrayList<RoomWordItem>)

@Delete
fun delete(user: RoomWordItem)
}
// We list entities included in the database
@Database(entities = [(RoomWordItem::class)], version = 1)
abstract class RoomWordDatabase : RoomDatabase() {
abstract fun wordDao(): RoomWordDao
}

Note: Room doesn’t support database access on the main thread unless you’ve called allowMainThreadQueries() on the builder because it might lock the UI for a long period of time.

roomWordDb = Room.databaseBuilder(applicationContext, RoomWordDatabase::class.java, DATABASE_NAME)
.
allowMainThreadQueries()
.fallbackToDestructiveMigration() //Allows Room to destructively recreate database tables if Migrations that would migrate old database schemas to the latest schema version are not found.
.build()
  • Querying the Database. We can use the DAO we created earlier to query our database
// Insert array of data into database
roomWordDb?.wordDao()?.insertAll(wordList)
// Search by value in database
roomWordDb?.wordDao()?.findByWord(searchText)
  • Room with RxJava. Since, by default database access is not allowed in room, we can use RxJava to handle background work.
// Create observable
private fun searchWordInRoom(searchText: String): Observable<String> {
return Observable.create { subscriber ->
val searchString = roomWordDb?.wordDao()?.findByWord(searchText)
// Our database emits the entity pojo
subscriber.onNext(searchString?.word.toString())
subscriber.onComplete()
}
}
// Subscribe to the observable
searchWordInRoom(searchText.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ resultSearch ->
wordListText.text = resultSearch.toString() //
Consuming the result from onNext to putinto textView
},
{ error ->
Toast.makeText(this, error.message, Toast.LENGTH_SHORT).show()
})

Great resource for Room and RxJava from Florina Muntenescu

Project Source code: Database in Kotlin

References:

  1. Kotlin Annotation Processor ~ Kotlinlang.org
  2. Starting with using Room ~ developer.android
  3. Room Persistence Library ~ developer.android
  4. What is ORM ~ wiki
  5. Room and RxJava ~ blog

--

--

Birat Rai
Birat Rai

Responses (1)