A Beginner's Guide to Using and Setting Up Room Database in Android with Java

Nitish Kumar Singh

Dec 9, 2023

Hello developers! In this blog post, we will learn and understand Room Database in Android using Java, including how to set up and use Room Database to store data in local storage in an Android App.

Room Database

Room Database is a persistence library in Android that provides an abstraction layer over SQLite. It simplifies database interactions by offering a fluent API, compile-time verification of SQL queries, and seamless integration with LiveData for real-time updates. By using Room Database, we can efficiently store our data in a structured way and interact with our data without writing much more code in Android applications.

Let's get started! Follow the step-by-step instructions below to set up and use Room Database.

Dependency Setup

To use Room Database, we need to include the following dependencies in our app's build.gradle file under the dependencies section.

// latest version of Room. at the time of writing this blog latest version is 2.6.1
implementation "androidx.room:room-runtime:2.6.1"
annotationProcessor "androidx.room:room-compiler:2.6.1"

The Room Database has many more dependencies for different use cases; you can explore them on the Save data in a local database using Room page.

In Room Database, Data entity, a Java class annotated with @Entity, Data access object (DAO), an interface annotated with @Dao, and an abstract subclass of RoomDatabase annotated with @Database are key components to store and interact with data.

Data entity

Data entities are classes annotated with the @Entity annotation, used to structure data fields. By default, the name of the class defines the table name, its fields' names define column names, and each object of it is a row in the database. Each data entity class defines a table in Room, and to create multiple tables, we need to create multiple Data entities. In an entity, one field must be annotated with @PrimaryKey annotation. The following code defines a User data entity.

@Entity
public class User {
    @PrimaryKey
    public int uid;
    public String firstName;
    public String lastName;
}

We can customize the name of the table and columns by using tableName and name properties of @Entity and @ColumnInfo annotation, and also define the primary key as auto-incremental by using autoGenerate = true property of @PrimaryKey annotation. The following code defines a customized User data entity.

@Entity(tableName = "users")
public class User {
    @PrimaryKey(autoGenerate = true)
    public int uid;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;
}

Visit the Define data using Room entities page on Android Developers Docs to explore more about it.

Data access object (DAO)

Data access object (DAO) is an interface annotated with @Dao annotation. In this interface, we define methods to insert, delete, update, and query data using @Insert, @Update, @Delete, and @Query annotations. The following code defines a DAO called UserDao with required methods to interact with data in the user table.

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    List<User> 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);
}

Defining delete, update, and insert methods are easy; just add annotations. But to define query methods, we need to have an understanding of SQL Queries. To learn about these queries, visit this page and to know more about Dao go to Accessing data using Room DAOs page.

RoomDatabase

To create a database, we need to create an abstract subclass of RoomDatabase annotated with @Database annotation. Here, we define abstract methods to get Dao objects and, using Dao objects, interact with the database. We also connect tables using entities and initialize version using the version property of @Database annotation. The following code is an example of a database.

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
}

Now, to interact with the database, we need to create an instance of AppDatabase and use the userDao method to get an Object of UserDao and perform any of the CRUD operations using Dao method, as shown in the following code.

AppDatabase db = Room.databaseBuilder(getApplicationContext(),
        AppDatabase.class, "database-name").build();
// Get object of UserDao
UserDao userDao = db.userDao();
// Get list of all users
List<User> users = userDao.getAll();

One more way of interacting with the database is to create a singleton pattern instance of the AppDatabase class using a static method of AppDatabase. So the following is the modified code of the AppDatabase class.

@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
    private static volatile AppDatabase INSTANCE;
    public static AppDatabase getInstance(Context context){
        if (INSTANCE==null){
            synchronized (AppDatabase.class){
                if (INSTANCE==null){
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AppDatabase.class,"MY_ROOM_DATABASE").build();
                }
            }
        }
        return INSTANCE;
    }

    public abstract UserDao userDao();
}

To learn more about RoomDatabase, visit this page.

Now, whenever we need to interact with the database to delete, update, insert, and query data, we use the static method of AppDatabase as shown in the code below.

    // Delete a user
    User user; // You have a user object to delete
    MyRoomDatabase.getInstance(activity).getUserDao().delete(user);
    // Insert users in bulk
    List<User> users = getBulkUsers();
    MyRoomDatabase.getInstance(activity).getUserDao().insertAll(users);
    // Get all users
    MyRoomDatabase.getInstance(activity).getUserDao().getAll();

Make sure you do any database operation in a background thread, or else you get an error.

I hope you learn and understand how to set up and use RoomDatabase in Android development and enjoy reading this blog post. Happy Coding!

Published on Dec 9, 2023
Comments (undefined)

Read More