The Room database in Android is a powerful library that simplifies data persistence, offering a modern alternative to SQLite. If you’ve ever wrestled with raw SQL queries or managed database versions manually, you’ll appreciate the improvements Room brings to the table. It allows Android developers to create a local database in Kotlin or Java with minimal boilerplate code, ensuring better compile-time safety and easier management of complex data operations. In this tutorial, you’ll learn how to implement a Room database in an Android app, making your data management more efficient and error-free.
To get started with Room, add the necessary dependencies to your build.gradle file. This will allow you to use Room in your Android project:
Add the Room Dependencies & plugins on the build.gradle.kts (Module :app)
plugins {
id("kotlin-kapt")
}
dependencies {
implementation (libs.room.runtime)
kapt (libs.room.compiler)
implementation(libs.room.ktx)
}
add the Dependencies versions on the libs.versions.toml file
dir: /gradle/libs.versions.toml
[versions]
room = "2.6.1"
[libraries]
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
Sync your project after adding these dependencies to ensure everything is set up correctly.
Entities in Room database represent tables. Here’s how you can create a simple User entity in Kotlin:
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
@ColumnInfo(name = "first_name") val firstName: String,
@ColumnInfo(name = "last_name") val lastName: String
)
This code defines a table named users with columns for id, first_name, and last_name. Room automatically handles these fields when you add or retrieve data from the database.
Data Access Objects (DAOs) are interfaces that define methods for interacting with your database. Here’s how you can create a UserDao in Kotlin:
@Dao
interface UserDao {
@Insert
suspend fun insert(user: User)
@Query("SELECT * FROM users WHERE id = :userId")
suspend fun getUserById(userId: Int): User?
@Delete
suspend fun deleteUser(user: User)
}
The next step is to create the Room database itself. This class should extend RoomDatabase:
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"userBD"
)
.build()
INSTANCE = instance
instance
}
}
}
}
This implementation ensures that only one instance of your Room database is created, following the Singleton pattern. This is critical for maintaining a consistent and thread-safe interaction with your database.
Once your Room database is set up, you can start using it in your app. Here’s a simple example:
val db = AppDatabase.getDatabase(context)
val userDao = db.userDao()
// Insert a new user
val newUser = User(firstName = "John", lastName = "Doe")
userDao.insert(newUser)