How to implement Room API in Android Application using Kotlin
What is Room API?
• Room API is a persistence library, part of the Android Jetpack.
• Android Jetpack is a suite of libraries, tools, and guidance to help developers write high-quality apps easier.
What is Room?
• Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
• Room is now considered as a better approach for data persistence than SQLiteDatabase or SQLiteOpenHelper.
• It makes it easier to work with SQLiteDatabase objects, decrease the amount of Boilerplate Code and verifying SQL queries at compile time.
Why should we use Room?
• Compile-time verification of SQL queries. each @Query and @Entity is checked at the compile time, that preserves your app from crash issues at runtime and not only it checks the only syntax, but also missing tables.
• No Boilerplate code
• Easily integrated with other Architecture components (like LiveData)
What are the major problems with SQLite
• There is no compile-time verification of raw SQL queries.
• For example, if you write a SQL query with a wrong column name that does not exist in real database then it will give exception during run time and you can not capture this issue during compile time.
• As your schema changes, you need to update the affected SQL queries manually. This process can be time-consuming and error-prone.
• You need to use lots of boilerplate code to convert between SQL queries and Java data objects (POJO).
Comparison Between Room vs SQLite
• SQLite deal with raw queries, But in Room, No raw queries
• No compile-time verification of raw SQLite queries. But in Room, Compile time checks of SQLite statements
• SQLite need lots of boilerplate code. But, Room does not use boilerplate code.
• SQLite are low-level, so more time, more effort to build apps, But in Room, used with ViewModel and LiveData makes it easy to code.
Room Components
• Room has three main components of Room DB:
• Entity
• Represents a table within the database
• Annotated with @Entity
• Dao
• Contains methods to access database
• Annotated with @Dao
• Database
• Contains the database holder and serves as the main access point in Room
• Annotated with @Database

Room Architecture

Example ROOM API using Kotlin
Let’s understand use of ROOM API with small application that will insert, update, delete and display username and password information.
Step to follows:
1. To use Room in your app, add the following dependencies to your app’s build.gradle file:
dependencies {
def room_version = “2.2.6”
implementation “androidx.room:room-runtime:$room_version”
kapt “androidx.room:room-compiler:$room_version”
// optional — Kotlin Extensions and Coroutines support for Room
implementation “androidx.room:room-ktx:$room_version”
// optional — Test helpers
testImplementation “androidx.room:room-testing:$room_version”
}
2. Creating Data Entity Class: Data.kt
The following code defines in User class. Each instance of User represents a row in a table in the app’s database. In this Data Entity class, UserTable is table name and uid, full_name, and password are field in this table. Uid data type is integer, full_name and password data type is string.
@Entity(tableName = “UserTable”)
data class User(
@PrimaryKey var uid:Int,
@ColumnInfo(name = “full_name”) var name: String?,
@ColumnInfo(name = “password”) var pwd: String?
)
3. Creating Data Access Object (DAO) Class: MyUserData.kt
The following code defines a DAO in MyUserDao class. MyUserDao class provides the methods that the rest of the app uses to interact with data in the table “UserTable”.
Dao
interface MyUserDao {
@Query(“select * from UserTable”)
fun userInfo(): List<User>
@Insert
fun insertRecord(user: User)
@Update
fun updateRecord(user: User)
@Delete
fun deleteRecord(user: User)
}
4. Creating Database Access Class to Hold Database: MyRoomDatabase.kt
The following code defines in MyRoomDatabase class to hold the database. This class defines the database configuration and serves as the app’s main access point to the persisted data. The database class must satisfy the following conditions:
a. The class must be annotated with a @Database annotation that includes an entities array that lists all of the data entities associated with the database.
b. The class must be an abstract class that extends RoomDatabase.
c. For each DAO class that is associated with the database, the database class must define an abstract method that has zero arguments and returns an instance of the DAO class.
@Database(entities = [User::class], version = 1)
abstract class MyRoomDatabase : RoomDatabase() {
abstract fun userDao(): MyUserDao
companion object {
@Volatile
private var INSTANCE: MyRoomDatabase? = null
fun getInstance(context: Context): MyRoomDatabase {
synchronized(this) {
var instance = INSTANCE
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
MyRoomDatabase::class.java,
“mydb.db”
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
}
return instance
}
}
}
}
5. At Last, Create MainActivity Class: MainActivity.kt
This class is main class, from which application is starting, here we define user interface and write code to interact with database created using ROOM API.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnDelete.setOnClickListener(View.OnClickListener {
val userid = txtUID.text.toString().toInt()
val user = User(userid,””,””)
try {
MyRoomDatabase.getInstance(this).userDao().deleteRecord(user)
displayMessage(“Information”, “Record Deleted”)
} catch (ex: SQLiteConstraintException) {
displayMessage(“Error”, ex.message)
}
})
btnUpdate.setOnClickListener(View.OnClickListener {
val userid = txtUID.text.toString().toInt()
val name=txtName.text.toString()
val pwd= txtPwd.text.toString()
val user = User(userid,name,pwd)
try {
MyRoomDatabase.getInstance(this).userDao().updateRecord(user)
displayMessage(“Information”, “Record Updated”)
} catch (ex: SQLiteConstraintException) {
displayMessage(“Error”, ex.message)
}
})
btnDisplay.setOnClickListener(View.OnClickListener {
val usersinfo = MyRoomDatabase.getInstance(this).userDao().userInfo()
val data = StringBuffer()
for (user in usersinfo!!) {
data.append(“User Id=${user?.uid}”.trimIndent())
data.append(“User name=${user?.name}”.trimIndent())
data.append(“User password=${user?.pwd}”.trimIndent())
}
displayMessage(“User Information”, data.toString())
})
btnDelete.setOnClickListener(View.OnClickListener {
val userid = txtUID.getText().toString().toInt()
val name=txtName.getText().toString()
val pwd=txtPwd.getText().toString()
val user = User(userid,name,pwd)
try {
MyRoomDatabase.getInstance(this).userDao().insertRecord(user)
Toast.makeText(applicationContext, “Record Inserted”, Toast.LENGTH_SHORT).show()
} catch (ex: SQLiteConstraintException) {
Toast.makeText(applicationContext, ex.message, Toast.LENGTH_SHORT).show()
}
})
}
fun displayMessage(title: String?, data: String?) {
val builder = AlertDialog.Builder(this@MainActivity)
builder.setTitle(title)
builder.setMessage(data)
builder.setCancelable(true)
builder.show()
}
}
If you want to download source code of it, just click on link below to download it from GitHub
For more information, you can watch this playlist: