- Android Room db tutorial for beginners in Kotlin
- Dependencies required to use Room in Android
- Must have components for Android Room
- Room Entity Classes.
- One entity class for each table
- Name of the database table
- Name of the table columns
- Primary Key
- Room DAO interface
- Function names
- Annotations
- Suspend keyword
- SQL Statement
- Room Insert functions
- Room Update and Delete functions
- Room Database Class
- Save data in a local database using Room Part of Android Jetpack.
- Setup
- Groovy
- Kotlin
- Primary components
- Sample implementation
- Data entity
- Kotlin
- Java
- Data access object (DAO)
- Kotlin
- Java
- Database
- Kotlin
- Java
- Usage
- Kotlin
- Java
- Kotlin
- Java
- Additional resources
- Samples
- Codelabs
- Blogs
Android Room db tutorial for beginners in Kotlin
Android Room is a ORM(object relational mapping) library created for SQLite. SQLite is the database management system we use to create databases in Android projects. In other words, Room acts as a layer on top of SQLite. Therefore, Room makes our coding much easier and efficient.
In this tutorial, we will learn about 3 major components required to use Room in an Android project.
Then, we will study insert, query, update and delete operations.
After that, we will build a simplest possible app example to demonstrate how room works.
Finally, we will build a complete Android MVVM project using the new knowledge we gained.
So, create a new Android Studio project. I just named my project as “RoomApp” .
Dependencies required to use Room in Android
Let’s start by adding “kotlin-kapt” plugin to to top of the gradle.
Then, we will add required dependencies for Room.
We need “kapt” dependency to use room annotations. And, we need “ktx” dependency to work with coroutines.
You will be able to get the latest version numbers from this link.
Next, we will add required dependencies for coroutines.
And, use this link to find latest version numbers of above dependencies.
In addition, we will also need the dependency for lifecycle components. (to use lifecycle scope)
Use this link to get the latest version numbers.
So, here is the final app level build.gradle file.
Must have components for Android Room
To use Room library, you need 3 code components. Entity classes, Dao interface and the database class.
Room Entity Classes.
One entity class for each table
- We need to create entity classes for each database table.
- Moreover, to qualify a class as a room entity class, we need to annotate it with @Entity .
- Holding data is the only purpose of these classes. So, we will create them as Kotlin data classes.
Name of the database table
- Database table will have the same name as the class name.
- And, if we need a different name, we could give that name as the value of the “tableName” property.
Name of the table columns
- Columns will have same names as the data class’s variable names.
- But, if we want different names we can provide them using @ColumnInfo
Primary Key
- Then, use the @PrimaryKey on the variable selected as the primary key of the table.
- If you want the primary key to auto generate set autoGenerate = true
In this small project we are going to have only one table. We will create a table to store details of books.
So, create a new Kotlin class and name it as “Book”. Here is the complete code.
Book.kt
As a result of above annotated data class, we will be able to create a table like this in the database.
Room DAO interface
Next, we need to create an interface . And, mark it with @Dao .
DAO stands for “Data Access Object”. This interface is where we define functions to deal with the database.
(you could also define DAO as an abstract class)
BookDao.kt
Function names
Function names are not important. You can give any name you like.
Annotations
But, annotating the function with correct annotation is very important.
For instance, we have annotated above “insertBook” function(method) with @Insert . Therefore, room will know that the purpose of that function is inserting data. Room library does not understand the function names. But, room recognizes annotations.
Suspend keyword
“Kotlin coroutines” is the current best practice to manage threads in android development. So, we are going to use them to execute database operations in a background thread. Therefore, we need to define these functions as suspending functions.
But, it is not required for query functions. Because, Room library uses its own dispatcher to run queries on a background thread. That’s why we haven’t modified above getAllBooks() function with suspend keyword.
SQL Statement
For basic Insert, Update and Delete functions we don’t need to write SQL statements.
But, we need to write a SQL statement for Query functions and for customized Update and Delete functions.
Room Insert functions
- All insert functions should annotate with @Insert
- There is no need to write a SQL query for insert functions.
- Return type is optional. Most of the time we write room insert functions without a return type.
- But, Room allows us to get the newly inserted row id as a “Long” value.
- For example, if the insert function has a single parameter, return type would be the new row id of type Long .
- On the other hand, if the parameter is an array or a collection, return type would be an array or a collection of Long values.
Room Update and Delete functions
- Update functions should annotate with @Update and delete functions should annotate with @Delete .
- These functions also don’t require a SQL statement. And, return types are optional.
- But, we can add an “int” return type.
- These functions return an “ int» value indicating the number of rows that were updated or deleted successfully
Room Database Class
Next, we will create a Room Database class. Create a new Kotlin class naming it as “BookDatabase”.
This class should be an abstract class. Most importantly, this should extend the “RoomDatabase” class.
Save data in a local database using Room Part of Android Jetpack.
Apps that handle non-trivial amounts of structured data can benefit greatly from persisting that data locally. The most common use case is to cache relevant pieces of data so that when the device cannot access the network, the user can still browse that content while they are offline.
The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite. In particular, Room provides the following benefits:
- Compile-time verification of SQL queries.
- Convenience annotations that minimize repetitive and error-prone boilerplate code.
- Streamlined database migration paths.
Because of these considerations, we highly recommend that you use Room instead of using the SQLite APIs directly.
Setup
To use Room in your app, add the following dependencies to your app’s build.gradle file:
Groovy
Kotlin
Primary components
There are three major components in Room:
- The database class that holds the database and serves as the main access point for the underlying connection to your app’s persisted data.
- Data entities that represent tables in your app’s database.
- Data access objects (DAOs) that provide methods that your app can use to query, update, insert, and delete data in the database.
The database class provides your app with instances of the DAOs associated with that database. In turn, the app can use the DAOs to retrieve data from the database as instances of the associated data entity objects. The app can also use the defined data entities to update rows from the corresponding tables, or to create new rows for insertion. Figure 1 illustrates the relationship between the different components of Room.
Sample implementation
This section presents an example implementation of a Room database with a single data entity and a single DAO.
Data entity
The following code defines a User data entity. Each instance of User represents a row in a user table in the app’s database.
Kotlin
@Entity data class User( @PrimaryKey val uid: Int, @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
Java
To learn more about data entities in Room, see Defining data using Room entities.
Data access object (DAO)
The following code defines a DAO called UserDao . UserDao provides the methods that the rest of the app uses to interact with data in the user table.
Kotlin
@Dao interface UserDao < @Query("SELECT * FROM user") fun getAll(): List@Query("SELECT * FROM user WHERE uid IN (:userIds)") fun loadAllByIds(userIds: IntArray): List @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") fun findByName(first: String, last: String): User @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) >
Java
@Dao public interface UserDao < @Query("SELECT * FROM user") ListgetAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User. users); @Delete void delete(User user); >
Database
The following code defines an AppDatabase class to hold the database. AppDatabase 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:
- 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.
- The class must be an abstract class that extends RoomDatabase .
- 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.
Kotlin
@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase()
Java
@Database(entities = , version = 1) public abstract class AppDatabase extends RoomDatabase
Note: If your app runs in a single process, you should follow the singleton design pattern when instantiating an AppDatabase object. Each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances within a single process.
If your app runs in multiple processes, include enableMultiInstanceInvalidation() in your database builder invocation. That way, when you have an instance of AppDatabase in each process, you can invalidate the shared database file in one process, and this invalidation automatically propagates to the instances of AppDatabase within other processes.
Usage
After you have defined the data entity, the DAO, and the database object, you can use the following code to create an instance of the database:
Kotlin
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
Java
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
You can then use the abstract methods from the AppDatabase to get an instance of the DAO. In turn, you can use the methods from the DAO instance to interact with the database:
Kotlin
val userDao = db.userDao() val users: List = userDao.getAll()
Java
UserDao userDao = db.userDao(); List users = userDao.getAll();
Additional resources
To learn more about Room, see the following additional resources:
Samples
Codelabs
Blogs
Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
Last updated 2023-06-26 UTC.