So until now we were fetching data from the server and directly displaying it to the user in the Open Event Android app. There are several problems in this approach if the user changes the fragment and then returns to the same fragment he will have to fetch the data again, valuable network gets wasted. There is also no offline support. So we decided to introduce a local database in the app. ROOM was without a doubt our first choice
What is ROOM?
According to the official documentation,
The Room persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
The library helps you create a cache of your app’s data on a device that’s running your app. This cache, which serves as your app’s single source of truth, allows users to view a consistent copy of key information within your app, regardless of whether users have an internet connection.
Let’s get started
Integration of the ROOM database majorly consists of 3 steps
1 Create an entity
2 Create a DAO
3 Create a Database
That’s it, you are done !
Create the entity
There are just 2 requirements in order to make a model an entity
First use @Entity annotation on the model class to make it an entity. Secondly you need at least one field with @PrimaryKey annotation.
This entity class represents a table in database and all its fields are the columns of the table.
@Type("event") @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy::class) @Entity data class Event( @Id(LongIdHandler::class) @PrimaryKey val id: Long, val name: String, val identifier: String, val startsAt: String)
Create DAO
Data Access Object or DAO for short are used to tell the database how to to put the data.
We can use the following annotations to perform simple SQL queries in ROOM
@Insert, @Update, @Delete for proper actions: inserting, updating and deleting records
@Query for creating queries — we can make select from the database
@Dao interface EventDao { @Insert(onConflict = REPLACE) fun insertEvents(events: List<Event>) @Insert(onConflict = REPLACE) fun insertEvent(event: Event) @Query("DELETE FROM Event") fun deleteAll() @Query("SELECT * from Event ORDER BY startsAt DESC") fun getAllEvents(): Flowable<List<Event>> @Query("SELECT * from Event WHERE id = :id") fun getEvent(id: Long): Flowable<Event> }
Create the Database
We need to create a public abstract class that extends RoomDatabase
After that annotate the class to be a Room database, declare the entities that belong in the database and set the version number. Listing the entities will create tables in the database.
Define the DAOs that work with the database. Make the database a singleton to prevent having multiple instances of the database opened at the same time. A lot has been said let’s have a look at the code now.
@Database(entities = [Event::class, User::class], version = 1) abstract class OpenEventDatabase : RoomDatabase() { abstract fun eventDao(): EventDao abstract fun userDao(): UserDao }
Room.databaseBuilder(androidApplication(),
OpenEventDatabase::class.java, "open_event_database")
.fallbackToDestructiveMigration()
.build()
The important thing here is that all operations must be done in the background thread. You can do it by using AsyncTask, Handler, RxJava or anything else.
Resources
- Room Official Documentation : https://developer.android.com/topic/libraries/architecture/room
- Google Code Lab :https://codelabs.developers.google.com/codelabs/android-room-with-a-view/#0