Android’s New Room

Rizvan Hawaldar
4 min readOct 31, 2017

Android’s Brand New Library “ Room ” , a part of Android Architecture Components

Introduction

Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.

Why Room ?

The core framework provides built-in support for working with raw SQL content. Although these APIs are powerful, they are fairly low-level and require a great deal of time and effort to use:

  • There is no compile-time verification of raw SQL queries. As your data graph changes, you need to update the affected SQL queries manually. This process can be time consuming and error prone.
  • You need to use lots of boilerplate code to convert between SQL queries and Java data objects.

Room takes care of these concerns for you while providing an abstraction layer over SQLite.

Room Architecture

Room architecture diagram

There are 3 major components in Room:

Database: You can use this component to create a database holder. The annotation defines the list of entities, and the class’s content defines the list of data access objects (DAOs) in the database. It is also the main access point for the underlying connection.

The annotated class should be an abstract class that extends RoomDatabase. At runtime, you can acquire an instance of it by calling Room.databaseBuilder() or Room.inMemoryDatabaseBuilder().

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

Entity: This component represents a class that holds a database row. For each entity, a database table is created to hold the items.

@Entity represents a database row. You must reference the entity class through the entities array in the Database class. Each field of the entity is persisted in the database unless you annotate it with @Ignore.

@Entity
public class User {
@PrimaryKey
private int uid;

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

@ColumnInfo(name = "last_name")
private String lastName;

// Getters and setters are ignored for brevity,
// but they're required for Room to work.
}

Note: Entities can have either an empty constructor (if the DAO class can access each persisted field) or a constructor whose parameters contain types and names that match those of the fields in the entity. Room can also use full or partial constructors, such as a constructor that receives only some of the fields.

DAO: This component represents a class or interface as a Data Access Object (DAO). DAOs are the main component of Room and are responsible for defining the methods that access the database.

The class that is annotated with @Database must contain an abstract method that has 0 arguments and returns the class that is annotated with @Dao. When generating the code at compile time, Room creates an implementation of this class.

@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);
}

Note: By accessing a database using a DAO class instead of query builders or direct queries, you can separate different components of your database architecture. Furthermore, DAOs allow you to easily mock database access as you test your app.

How to use it?

Add dependencies to your project :

We need to add Google Maven repository to our build.gradle file:

allprojects {
repositories {
jcenter()
maven { url 'https://maven.google.com' }
}
}

And then we can add proper dependencies to app/build.gradle file:

implementation "android.arch.persistence.room:runtime:1.0.0-rc1"
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-rc1"

You cannot access database on main thread so use AsyncTask, Handler, RxJava or anything else.

App Database Class

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

private static final String DB_NAME = "UserDatabase.db";
private static volatile AppDatabase appDatabase;

static synchronized AppDatabase getInstance(Context context){
if (appDatabase == null) appDatabase = create(context);
return appDatabase;
}

private static AppDatabase create(final Context context){
return Room.databaseBuilder(context,AppDatabase.class,DB_NAME).build();
}

public abstract UserDao userDao();

}

Finally Add Data & Get Data example

/**
* Insert and get data using Database Async way
*/
AsyncTask.execute(new Runnable() {
@Override
public void run() {

//Insert Data
AppDatabase.getInstance(context).userDao().insert(new User(1,"James","Mathew"));
// Get Data AppDatabase.getInstance(context).userDao().getAllUsers(); }
});

Android Sample App with Room library implementation can be found here : Room Library Sample App

Official documentation available here : Room Persistence Library

Learned something? Clap your 👏 to say “thanks!” and help others find this article.

That’s All for Now.

Please follow my other stories as well.

How to update Android App without Playstore?

https://medium.com/@rizvan/android-in-app-update-feature-404d3e2a0486

--

--

Rizvan Hawaldar

Android dev turned Full stack dev, building ai apps in free time, gaining expertise in Kotlin (MPM/ServerSide/Android). http://github.com/llRizvanll