Android Jetpack: Room
Articles Blog

Android Jetpack: Room

August 24, 2019

At Google I/O 2017 we opened the door to
Room, a persistence library that provides an
abstraction layer over SQ Lite. Now, Room has reached version
2.0 and is part of Jetpack. We fixed the bugs you reported,
and added some of the features you asked for. Let’s go over Room’s
main components and see what queries
are supported, how to implement
migrations, and how to test your work with the database. Let’s say that you want
to have a table of users, and you want every
row of that table to be an instance
of the user class. Annotate your class
with that entity. Define the table
name if you don’t want to use the
name of the class as tableName, set the
mandatory primary key, and the optional column info. But only if you want to
change the name of the column. Otherwise the
field name is used. And that’s it. Room will take care of the
creation of the user table for you. So that’s how the
entity is done. But we need a way to access
the data in the database. We do that with data access
objects, DAOs for short. More precisely,
create an interface. Annotate it with @Dao. In this interface
declare all the methods needed to work
with the database, annotating them with the
corresponding SQL query. Room takes care of implementing
these methods for you. The supported queries are
insert, update, delete, query, and rawquery. All of them except
rawquery are checked at compile time, which
means that if you write an invalid query, you’ll
find this out immediately. The class that puts together
the entities and the DAOs is the room database. Create an extra class that
extends the Room database. Annotate it. Declare the entities and
the corresponding DAOs. Let’s take a closer
look at the queries. The return type of
query and rawquery can be the entire entity, but
also a subset of its fields. If you’re working with
Guava or with Optional from the Java util
package, you can also use them as return types. So this means that if
there are no values to satisfy your
query, then your query will return Optional.empty
or Optional.absent, depending on which Optional
you’re working with. All of these queries
are synchronous, meaning that they will
be run on the same thread that you are
triggering them from. Room ensures you follow best
practices by throwing an error if you run queries
on the main thread. So use your preferred method
of handling threads in Android, and make sure you are
off the main thread. Room also supports
asynchronous query when working with
LiveData or RXJava. What’s more, the queries
that return LiveData, or [? flowable, ?] are
observable queries, meaning that you will
get notified every time the data in the table,
or tables, updates. Whenever you alter your
database schema, either because you’ve added or
renamed a column or a table, you need to tell the database
how to handle that change. In order to do that
in your database class you’ll need to first update
your database version. Second, implement
a migration class, which defines how to handle the
migration from the old schema to the new one. And then, thirdly, add
that migration class as a parameter to
the database filter. After triggering
the migrations, Room validates the schema for you to
ensure that the migration was done correctly. If you don’t want to
handle migrations, and you don’t need to
preserve your database data, call
fallbacktodestructivemigrations when building the database. To destructively
recreate the database only from a specific
version on, call fallbacktodestru
ctivemigrationfrom. And provide the number
for that version. So we have our entities, DAOs,
database, and migrations. How do we test that? To test the DAOs, you’ll need
to implement an Android JUnit test that creates an
in-memory database. The in-memory database
holds the data only for as long as
the process is alive, meaning that after every test,
the database is destroyed. To test asynchronous queries,
use an instanttaskexecutorrule to execute each
task synchronously. In your app’s
implementation, you’ll end up referencing the
DAOs in other classes. To unit test those
classes, just mock the DAO or implement the fake version. Here’s another tip. To implement Espresso
tests, covering code that uses
asynchronous queries, extend the
countingtaskexecutorrule to count the tasks as
they start and finish. Finally, don’t forget
to test the migrations. Explore the database
schema first, and then use another handy test
rule, the migrationtesthelper. This class allows you to
create the database in an older version, and run and
validate each migration. All you need to do is
check that the data you inserted in
the older version is also present
after the migration. OK. So let’s summarize this. Less boilerplate code. Compile-time checked queries. Ease of implementing migrations. A high degree of testability. And checks for
keeping the database work away from the main thread. All of these
qualities of Room make it easier and more pleasant to
work with databases, helping you deliver better apps. [ROCKET BLASTING OFF]

Only registered users can comment.

  1. Hey Florina Muntenescu, Is there any possibility of creating and accessing database dynamically like Creating Duo, DTO, and Database with room dynamically

  2. Where has version 2.0 been published? The Google Maven repository only lists 2.0.0-alpha1. Release notes are missing, too.

  3. Well, she's Romanian.. But however she's good on English, and you can easly understand, what does she wants to tell to us, and of course I have watched this video not for learning but to impress myself that she is a Romanian and she became a Android Developer and presentator of Google Developers, Yeah she's earning a lot, but i don't take care about it, i also want to become an Android Developer not for money, but to show to people that i can break the ice, i have only 12 years and still understanding this, but however i'm learning everyday a little bit, and with this tempo i will know perfectly java language for android. So if you are an android beginner developer, don't worry about this, everyone was like you when they wanted to start this, soo don't take the Android Studio yet, because it will be hard to understand for you, just go to your phone and download Sketchware from Google Play, (In case that you are a beginner) . In this app you will develop your app also like android studio, but there codes are blocks, and every specific block is an code, but is much easier to understand, soo guys please leave a like on this comment, i hope that i helped you, Thanks

  4. Hi Florina!!! As i see You are a pretty good at Room stuff in the whole world. Could you please help me understand one aspect of it. I am new at programming Android. So this is my kind of problem i got stuck with. I pretty much understand how this Room works. Anyway, I've got SQLite database file with 1000's of rows of data. And i want my project to fetch data from this .db file and populate RoomDatabase. But all solutions on Stackoverflow seem to fail. Can you show me the way to do it, please? Thank you.

  5. How can i use a predifined sqlite.db with room? I have search the last hours but i can not find any solution. I think that this must be solved from google except if you already did it and i can not find it!

  6. There is typo:
    The method It's not called fallbackToDestructiveMigrationsFrom() but fallbackToDestructiveMigrationFrom()

    Without an S in Migration

  7. Thankyou Sister for your tuto!Can you help me i have this error:cannot access database on the main thread since it may potentially lock the UI for a long time.I use arch the Dao class:@SuppressWarnings(RoomWarnings.CURSOR_MISMATCH)

    @Query("SELECT * FROM user_table WHERE email=:email AND mdp=:mdp AND role=:role")

    User getUser(String email,String mdp,String role);
    ,the repository class:public User getUser(String email,String mdp,String role)



    return user;

    } and the viewmodel this:public User getUser(String username,String mdp,String role)


    return userrepository.getUser(username,mdp,role);

    } an i want use it for call it in the mainActivity like this:user=userViewModel.getUser(login,mdp,item);Thankyou!

  8. Seems like Google is anti-boilerplate when it comes to just about anything. Seriously, I have no issues with boilerplates.

  9. You guys need to clarify your relationships documentation. It's misleading and barely comprehensible. Room is supposed to reduce "boilerplate code" but a single join query requires way too much complex code.

Leave a Reply

Your email address will not be published. Required fields are marked *