Room is a persistence library that provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQL. It is built on top of Android's architecture components and follows the repository pattern, making it easier to manage data in your applications. This tutorial will guide you through setting up Room in a Kotlin project, creating entities, defining DAOs (Data Access Objects), and performing CRUD operations.
To use Room in your Kotlin project, you need to add the necessary dependencies in your build.gradle file. Open your app-level build.gradle and include the following:
dependencies {
def room_version = "2.5.0"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor
// Optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
}
Sync your project with Gradle files to download the dependencies.
An entity in Room represents a table in the database. Each property of the entity corresponds to a column in the table. Here's how you can define an entity:
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true) val id: Int,
val name: String,
val email: String
)
In this example, User is an entity with three fields: id, name, and email. The @Entity annotation marks the class as a database table, and @PrimaryKey specifies the primary key of the table.
A DAO (Data Access Object) provides methods for accessing data in the database. Room uses these methods to generate SQL queries at compile time.
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAllUsers(): Flow<List<User>>
@Insert
suspend fun insertUser(user: User)
}
In this DAO, getAllUsers is a method that retrieves all users from the database as a Flow, and insertUser inserts a new user into the database. The @Query annotation is used to define SQL queries, and @Insert specifies an insert operation.
The database class holds the configuration information for Room, such as the entities and version number. It also provides access points to the DAOs.
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
The @Database annotation specifies the entities and version of the database. The AppDatabase class extends RoomDatabase and provides an abstract method for each DAO.
You need to initialize the database in your application or activity. It's recommended to use a singleton pattern to ensure that only one instance of the database is created.
import android.content.Context
import androidx.room.Room
object DatabaseClient {
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
synchronized(this) {
INSTANCE = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java, "user_database"
).build()
}
}
return INSTANCE!!
}
}
Now that you have set up the database and DAO, you can perform CRUD operations.
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
fun insertUser(context: Context, user: User) {
GlobalScope.launch {
val db = DatabaseClient.getDatabase(context)
db.userDao().insertUser(user)
}
}
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import kotlinx.coroutines.flow.collectLatest
fun getUsers(context: Context): LiveData<List<User>> {
val usersLiveData = MutableLiveData<List<User>>()
GlobalScope.launch {
DatabaseClient.getDatabase(context).userDao().getAllUsers().collectLatest { users ->
usersLiveData.value = users
}
}
return usersLiveData
}
You can define additional methods in your DAO for updating and deleting data:
@Dao
interface UserDao {
// Existing methods...
@Update
suspend fun updateUser(user: User)
@Delete
suspend fun deleteUser(user: User)
}
And use them similarly to the insert method.
Room is a powerful persistence library that simplifies database operations in Android applications. By following this tutorial, you should have a solid understanding of how to set up Room, define entities, create DAOs, and perform CRUD operations. Remember to apply best practices for optimal performance and maintainability.