Android Architecture Components: Room — Relationships

Introduction

One-to-many relation

import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;

@Entity
public class User {
@PrimaryKey public final int id;
public final String login;
public final String avatarUrl;

public User(int id, String login, String avatarUrl) {
this.id = id;
this.login = login;
this.avatarUrl = avatarUrl;
}
}
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.PrimaryKey;

import static android.arch.persistence.room.ForeignKey.CASCADE;

@Entity(foreignKeys = @ForeignKey(entity = User.class,
parentColumns = "id",
childColumns = "userId",
onDelete = CASCADE))
public class Repo {
@PrimaryKey public final int id;
public final String name;
public final String url;
public final int userId;

public Repo(final int id, String name, String url,
final int userId) {
this.id = id;
this.name = name;
this.url = url;
this.userId = userId;
}
}

SQL query

import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import java.util.List;

@Dao
public interface RepoDao {

@Insert
void insert(Repo repo);

@Update
void update(Repo... repos);

@Delete
void delete(Repo... repos);
@Query("SELECT * FROM repo")
List<Repo> getAllRepos();

@Query("SELECT * FROM repo WHERE userId=:userId")
List<Repo> findRepositoriesForUser(final int userId);
}
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Update;

@Dao
public interface UserDao {

@Insert
void insert(User... user);

@Update
void update(User... user);

@Delete
void delete(User... user);
}
@Database(entities = { Repo.class, User.class },
version = 1)
public abstract class RepoDatabase extends RoomDatabase {
... public abstract RepoDao getRepoDao();
public abstract UserDao getUserDao();
}
RepoDao repoDao = RepoDatabase
.getInstance(context)
.getRepoDao();

UserDao userDao = RepoDatabase
.getInstance(context)
.getUserDao();

userDao.insert(new User(1,
"Jake Wharton",
"https://avatars0.githubusercontent.com/u/66577"));

repoDao.insert(new Repo(1,
"square/retrofit",
"https://github.com/square/retrofit",
1));

List<Repo> repositoriesForUser = repoDao.
findRepositoriesForUser(1);

Many-to-many relation

import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;

@Entity
public class User {
@PrimaryKey
public final int id;
public final String login;
public final String avatarUrl;

public User(int id, String login, String avatarUrl) {
this.id = id;
this.login = login;
this.avatarUrl = avatarUrl;
}
}
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;

@Entity
public class Repo {
@PrimaryKey
public final int id;
public final String name;
public final String url;

public Repo(int id, String name, String url) {
this.id = id;
this.name = name;
this.url = url;
}
}
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;

@Entity(tableName = "user_repo_join",
primaryKeys = { "userId", "repoId" },
foreignKeys = {
@ForeignKey(entity = User.class,
parentColumns = "id",
childColumns = "userId"),
@ForeignKey(entity = Repo.class,
parentColumns = "id",
childColumns = "repoId")
})
public class UserRepoJoin {
public final int userId;
public final int repoId;

public UserRepoJoin(final int userId, final int repoId) {
this.userId = userId;
this.repoId = repoId;
}
}
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import java.util.List;

@Dao
public interface UserRepoJoinDao {
@Insert
void insert(UserRepoJoin userRepoJoin);

@Query("SELECT * FROM user INNER JOIN user_repo_join ON
user.id=user_repo_join.userId WHERE
user_repo_join.repoId=:repoId")
List<User> getUsersForRepository(final int repoId);

@Query("SELECT * FROM repo INNER JOIN user_repo_join ON
repo.id=user_repo_join.repoId WHERE
user_repo_join.userId=:userId")
List<Repo> getRepositoriesForUsers(final int userId);
}
@Database(entities = { Repo.class, User.class, UserRepoJoin.class },
version = 1)
public abstract class RepoDatabase extends RoomDatabase {
... public abstract RepoDao getRepoDao();
public abstract UserDao getUserDao();
public abstract UserRepoJoinDao getUserRepoJoinDao();
}
RepoDao repoDao = RepoDatabase
.getInstance(context)
.getRepoDao();

UserDao userDao = RepoDatabase
.getInstance(context)
.getUserDao();

UserRepoJoinDao userRepoJoinDao = RepoDatabase
.getInstance(context)
.getUserRepoJoinDao();
userDao.insert(new User(1,
"Jake Wharton",
"https://avatars0.githubusercontent.com/u/66577"));

repoDao.insert(new Repo(1,
"square/retrofit",
"https://github.com/square/retrofit"));
userRepoJoinDao.insert(new UserRepoJoin(1, 1));

Using @Relation annotation

@Entity
public class User {
@PrimaryKey public final int id;
public final String login;
public final String avatarUrl;

public User(int id, String login, String avatarUrl) {
this.id = id;
this.login = login;
this.avatarUrl = avatarUrl;
}
}
@Entity
public class Repo {
@PrimaryKey public final int id;
public final String name;
public final String url;
public final int userId;

public Repo(int id, String name, String url, int userId) {
this.id = id;
this.name = name;
this.url = url;
this.userId = userId;
}
}
public class UserWithRepos {
@Embedded public User user;

@Relation(parentColumn = "id",
entityColumn = "userId") public List<Repo> repoList;
}
@Dao
public interface UserWithReposDao {

@Query("SELECT * from user")
public List<UserWithRepos> getUsersWithRepos();

}

Conclusion

Flutter GDE / Android & Flutter Developer / blogger / speaker / cat owner / travel enthusiast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store