Intro to Room Persistence Library

In almost every mobile app, we need to cache/save data on the client side. You want your data to be saved in a reliable and most manageable way.

In Google I/O 2017, Google introduced Room persistence layer which is an abstraction layer over SQLite. Essentially, it would allow you to map java objects into SQLite tables/fields instead of having to write complex SQL/SQLite boilerplates. A lot of useful third party abstraction like GreenDao, Ormlite were already available before that. However, if you need an “SQL” based database on Android, Room is probably the most reliable solution now. (If you don’t need SQL based, e.g, you have few or no relationship, you can check Realm mobile database)

Without further due, let see how we can use this new Library which comes in-built with Android SDK latest version.

So, you will have to set the Compile SDK to latest version in your app.gradle:

compileSdkVersion 26

Add Room Dependencies

compile 'android.arch.persistence.room:runtime:1.0.0-alpha8'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0-alpha8'

Annotate a model as Entity

Using annotation you can persist any of your models to Room.

@Entity
public class User {

    @PrimaryKey
    private String userId;

    private String firstName;
    private String lastName;
    private String nickname;
}

We added 2 annotations “Entity” for the Model which we want to persist, we also need to specify the “Primary key” with any one field. So far so good.

Create DAO interface

This is where you define the list of methods (operations) which can be done on your entity. If you have used, “Retrofit”, it is similar to API service where we define all API methods. Room also uses Annotations for us to define list of operations which we can perform on the object. E.g, we want to insert/delete a User object.

@Dao
public interface UserDao {
    @Insert
    void insert(User item);

    @Insert
    void insertAll(List<User> items);

    @Delete
    void delete(User item);

    @Query("DELETE FROM user")
    void deleteAll();

    @Query("SELECT * FROM user")
    List<User> getListUser();
}

We can use “Insert” and “Delete” annotations for inserting and deleting. To fetch users data from DB, we will need to use “Query”. We will have to write a small SQL but the good thing here is that Room will tell you if there is any error in your SQL at compile-time.

Create app Database class

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

    private static AppDatabase INSTANCE;

    public static AppDatabase getDatabase(Context context) {
        if (INSTANCE == null) {
            INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "app_database")
                    .allowMainThreadQueries() // Avoid calling main thread if large dataset
                    .fallbackToDestructiveMigration() // Add custom migration when needed
                    .build();
        }
        return INSTANCE;
    }

    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            // Since we didn't alter the table, there's nothing else to do here.
        }
    };

    public static void destroyInstance() {
        INSTANCE = null;
    }
    public abstract UserDao userDao();
}

You can create a static instance of your Database inside you Application class

AppDatabase.getDatabase(context);
UserDao userDao = AppDatabase.getDatabase(context).userDao();

Or if you are using Dagger 2:

@Module
public class DatabaseModule {

    public DatabaseModule() {}

    @Singleton
    @Provides
    public AppDatabase getDBInstance(Context context) {
        return AppDatabase.getDatabase(context);
    }

    @Singleton
    @Provides
    public UserDao getUserDao(Context context) {
        return getDBInstance(context).userDao();
    }
}

UserDao – Insert/Delete/Select User objects

userDao.insert(new User());

We can access all of the methods we have defined inside UserDao interface so that we save or get data to/from Room Database.

Note that I have allow transactions on Main Thread (“allowMainThreadQueries” inside AppDatabase class). However if you have bigger database transaction, e.g, you can use “RxJava” for threading.

This was a basic introduction to Room to get started. We haven’t used any relationship and we are only storing one table. Something to lookup to maybe in another blog post. If you have any queries, please let me know. Enjoy!! Happy coding!!!

Regards,

Please Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s