Room’s database relationships in Android

Tram Ho

An important part of database design is to divide data into related tables and pull data together in meaningful ways.

With Room 2.2 database, we will support all possible relationships between tables: one-to-one, one-to-many and many-to-many, with an annotation: Relation .

One-to-one relationship

An easy example in this case is as follows: a person may own a dog and a dog may have only one owner. This is a one-to-one relationship.

To show this relationship in the database, we create two tables: Dog and Owner , where Dog table has reference to owner id , Owner table has reference to dog id .

In Room, we create 2 models as follows:

To display all the dogs and their owners on the screen, we create a DogAndOwner class as follows:

To query using SQLite, we need to do two things:

  1. Run 2 queries: one is to retrieve all owners, the other is to retrieve all dogs based on owner ids.
  2. Handling object mapping.

To query List <DogAndOwner> using Room, we do not need to do the above two things, instead, we only need to use the Relation annotation

In this example, when Dog has owner information, we add the Relation annotation to the Dog variable, specifying that the ownerId column corresponds to dogOwnerId :

The DAO query class will look like this:

One-to-many relationship

Returning to the example mentioned, we now have a one-to-many relationship between Dog and Owner. The model of the database we defined earlier has not changed.

Now, to display the list of owners with dogs, we need to create a new class like this:

To avoid running two separate queries, we can define a one-to-many relationship between Dog and Owner, using the Relation annotation of List <Dog>:

The DAO class will look like this:

Many-to-many relationships

Now, let’s consider the case where one owner may own multiple dogs, and one dog may have multiple owners. To show this relationship, the Dog table and the Owner table we defined earlier are not enough.

A dog can have many owners, we need to have multiple dog ids, corresponding to different owner ids. Since dogId is the primary key in the Dog table, we cannot insert multiple dogs with the same id.

To solve this problem, we need to create a combined table (also known as a cross reference table) holding pairs (dogId, ownId):

If we want to get all the owners and dogs: List <OwnerWithDogs>, using only SQLite query, we need to write 2 queries: one takes all owners and one joins the Dog and DogOwnerCrossRef tables:

To do this in Room, we need to update the OwnerWithDogs class and tell Room that to get Dog data, it needs to use the DogOwnerCrossRef linked table:

In the DAO class, we need to select from Owners and return the correct class:

Share the news now

Source : Viblo