Last year 2017 Google announced a more secure and robust architecture to allow smooth database access while harnessing the full power of SQLite called Room Library. The Room Persistence library helps your app to create a cache on your device. In this blog, we are going to discuss Room Library and its implementation.
Persistence in Android?
To persist data in Android different companaies provide various solutions.
But inside our Android framework we have three things which come with our standard library:
1. ContentProviders
2. SQLite
3. SharedPreferences
But In all above three if we want to store data in a structured form we have to go with SQLiteDatabase. SQLite is something we have been shipping from Android 1 and it is a proven technology works very well but to write a simple query in SQLite it takes a lot of stuff.
To overcome this Google announced an object mapping library for SQLite called Room.
What is Room Database?
Room Library is a new and more smooth way to create the database in your Android app. Room Library eliminates a lot of boilerplate code which we write previously in an implementation of SQLite database in our app. Room Library provides an abstraction layer over SQLiteDatabase and helps us to create a cache of our app’s data on a device that’s running our app. Room is ORM between Java classes and SQLite.In Room, we cannot have complex nesting of objects like other ORM solutions provide.
Room majorly provides three components:
1. Database:
It contains the database holder and acts as the main access point for our app’s persisted data. our database class must be annotated with @Database and must satisfy some conditions:
- Database class must extend RoomDatabase.
- Database class must contain the list of entities associated with the database within the annotation.
- Database class must have an abstract method that has zero arguments and returns the class that is annotated with @Dao.
At runtime, we can acquire an instance of Database by calling Room.databaseBuilder() or Room.inMemoryDatabaseBuilder().
2. Entity: It represents a table within the database.
3. DAO: It contains the methods used for accessing the database.
Get Started with Room implementation
1. Create a new project with a default empty activity in Android Studio.
2. Add google Maven Repository to top-level build.gradle.
allprojects { repositories { google() jcenter() } }
3. Add the following code in build.gradle (app level) inside dependency block.
def room_version = "1.1.0" // or, for latest rc, use "1.1.1-rc1" implementation "android.arch.persistence.room:runtime:$room_version" annotationProcessor "android.arch.persistence.room:compiler:$room_version" // optional - RxJava support for Room implementation "android.arch.persistence.room:rxjava2:$room_version" // optional - Guava support for Room, including Optional and ListenableFuture implementation "android.arch.persistence.room:guava:$room_version" // Test helpers testImplementation "android.arch.persistence.room:testing:$room_version"
4. Create an Entity.
We are creating an entity called Employee .Employee is a table which is used to store data. To make our Employee class familiar to RoomDatabase, we need to annotate it with
@Entity annotation. Annotations identify how each part of this class relates to an entry in the database.
Room uses the following information to generate code.
@Entity(tableName = “EMPLOYEE_TABLE”)
Every @Entity class must represent an entity. Here our table name is different from our entity class, so define it like above line.
@PrimaryKey
This annotation used to make primary key because every entity needs a primary key.
@NonNull
This annotation defines that a parameter, field, or method never return a null value.
@ColumnInfo(name = Id_Proof)
This annotation specifies the name of the column in the database if we want our column name must be different from member variable.
@Entity(tableName = "Employee_Table") public class Emplyee { @PrimaryKey(autoGenerate = true) private int id; private String name; private long salary; private int age; private String designaion; public Emplyee(int id, String name, long salary, int age, String designaion) { this.id = id; this.name = name; this.salary = salary; this.age = age; this.designaion = designaion; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getSalary() { return salary; } public void setSalary(long salary) { this.salary = salary; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getDesignaion() { return designaion; } public void setDesignaion(String designaion) { this.designaion = designaion; } }
5. Create DAO class
DAO means data access object, DAO must be an interface or abstract class and annotate it with @Dao annotation to identify it is a DAO class for Room.
In DAO we have to specify SQL queries and associate it with method calls.
Here we are creating a DAO class and write some queries to interact with the database.
Implementation of DAO:
- Create the new interface and called it EmployeeDao.
- Annotate your DAO class with the @Dao annotation to make it familiar with the room.
- Annotate your methods with an annotation like @Insert, @Query, @Delete which are used to interact with the database.
@Dao public interface EmployeeDAO { @Insert void insert(Emplyee emp); @Query("Delete from Employee_Table") void deleteAllEmployee(); @Query("Select * from employee_table order by name ASC") List<Emplyee> getEmployeeList(); }
6. Add a Room database
It is a database abstract layer which works on top of an SQLiteDatabase To interact with database room uses DAO classes which we discussed above. It provides a compile-time check of SQLite statements. Our Database class must extend RoomDatabase. We have to make one instance of Room Database for our whole app.
Implementation Of RoomDatabase:
- To create Database class that class must satisfy some following condition:
- Database class must be an abstract public class.
- Database class must extend RoomDatabase.
- Database class must be annotated and declare the entities that belong to the database and set the version number. @Database(entities = {Emplyee.class} , version = 1).
2. Define DAO class that work with database and provides an abstract getter method for each @Dao. i.e. public abstract EmployeeDAO employeeDao();
3. Create your database a singleton to avoid the threat of multiple instances opened at the same time.
@Database(entities = Emplyee.class, version = 1) abstract class EmployeeDatabase extends RoomDatabase { public abstract EmployeeDAO employeeDAO(); private static EmployeeDatabase databaseInstance; static EmployeeDatabase getDatabase(final Context context) { if (databaseInstance == null) { synchronized (EmployeeDatabase.class) { if (databaseInstance == null) { databaseInstance = Room.databaseBuilder(context.getApplicationContext() , EmployeeDatabase.class , "Employee_Database").build(); } } } return databaseInstance; } }