Introduction
Room Database is a powerful and efficient library provided by Android for local data storage. In this blog post, we will explore how to perform the four fundamental CRUD operations (Create, Read, Update, Delete) using Room Database in an Android app, using Kotlin as the programming language. By the end of this tutorial, you will have a clear understanding of how to integrate Room into your Android project and manage your local database operations seamlessly.
Prerequisites
Before we begin, ensure you have the following prerequisites:
- Basic knowledge of Android development using Kotlin.
- Android Studio is installed on your machine.
Step 1: Setting Up Room Database
To use Room Database in your Android project, start by adding the necessary dependencies to your app-level build.gradle file:
gradle
dependencies {
implementation “androidx.room:room-ktx:2.4.0”
kapt “androidx.room:room-compiler:2.4.0”
}
Sync your project to download the dependencies.
Step 2: Creating the Entity
The first step in setting up the Room Database is to create an Entity class that represents your table. An Entity is a Kotlin data class annotated with @Entity. Each field in the class represents a column in the table.
@Entity(tableName = “users”)
data class User(
@PrimaryKey(autoGenerate = true)
val id: Long = 0L,
@ColumnInfo(name = “name”)
val name: String,
@ColumnInfo(name = “age”)
val age: Int )
In this example, we have created an Entity class for a simple “users” table with columns for “id“, “name“, and “age“.
Step 3: Creating the DAO (Data Access Object)
Next, we need to define the Data Access Object (DAO) interface, which will contain methods for performing database operations. Annotate the DAO interface with @Dao.
@Dao
interface UserDao {
@Insert
suspend fun insertUser(user: User)
@Update
suspend fun updateUser(user: User)
@Delete
suspend fun deleteUser(user: User)
@Query(“SELECT * FROM users”)
suspend fun getAllUsers(): List<User> }
In this DAO interface, we have defined four methods: insertUser(), updateUser(), deleteUser(), and getAllUsers(). Each method is annotated with the relevant Room annotations (@Insert, @Update, @Delete, and @Query) to indicate the corresponding database operation.
Step 4: Creating the Room Database
Now, it’s time to create the Room Database itself. Create an abstract class that extends RoomDatabase, and define abstract methods for obtaining the DAO.
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao }
In this example, we have created an abstract class AppDatabase, which represents the Room Database. We have defined an abstract method userDao() that returns the UserDao interface.
Step 5: Initializing the Room Database
To initialize the Room Database, we use the Singleton pattern to ensure only one instance of the database is created throughout the application lifecycle.
object DatabaseProvider {
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
“app_database”
).build()
INSTANCE = instance
instance
}
}
}
In this example, we have created a DatabaseProvider object that provides access to the Room Database. It uses databaseBuilder() to create the database instance and synchronizes to ensure thread safety.
Step 6: Performing CRUD Operations
Now that we have set up the Room Database and DAO, let’s perform the CRUD operations in our app.
Insert Operation
suspend fun insertUser(user: User) {
withContext(Dispatchers.IO) {
DatabaseProvider.getDatabase(context).userDao().insertUser(user)
}
}
Update Operation
suspend fun updateUser(user: User) {
withContext(Dispatchers.IO) {
DatabaseProvider.getDatabase(context).userDao().updateUser(user)
}
}
Delete Operation
suspend fun deleteUser(user: User) {
withContext(Dispatchers.IO) {
DatabaseProvider.getDatabase(context).userDao().deleteUser(user)
}
}
Fetch Operation
suspend fun getAllUsers(): List<User> {
return withContext(Dispatchers.IO) {
DatabaseProvider.getDatabase(context).userDao().getAllUsers()
}
}
In each operation, we are using Kotlin coroutines to perform the database operations asynchronously on a background thread (Dispatchers.IO) to avoid blocking the main UI thread.
Conclusion
In this blog post, we explored how to use Room Database in an Android app using Kotlin to perform CRUD operations. We covered setting up Room, creating an Entity class, defining the DAO interface, initializing the Room Database, and implementing the CRUD operations. Room simplifies database management in Android apps, providing a robust and efficient solution for local data storage.