1 対 1 のリレーションを定義してクエリを実行する

2 つのエンティティ間の 1 対 1 のリレーションとは、親エンティティの各インスタンスが子エンティティの 1 つのインスタンスに対応するリレーション、あるいはその逆のリレーションです。

たとえば、音楽ストリーミング アプリで、ユーザーが自分の所有する曲のライブラリを持っている場合を考えてみましょう。各ユーザーはライブラリを 1 つだけ持ち、各ライブラリは 1 人のユーザーに対応しています。したがって、User エンティティと Library エンティティの間には 1 対 1 のリレーションがあります。

データベースで 1 対 1 の関係を定義してクエリを実行する手順は次のとおりです。

  1. リレーションを定義する: 両方のエンティティのクラスを作成し、一方がもう一方の主キーを参照するようにします。
  2. エンティティをクエリする: 新しいデータクラスで関係をモデル化し、関連データを取得するメソッドを作成します。

関係を定義する

1 対 1 のリレーションを定義するには、まず 2 つのエンティティにそれぞれクラスを作成します。一方のエンティティには、他方のエンティティの主キーへの参照である変数を含める必要があります。

Kotlin

@Entity
data class User(
    @PrimaryKey val userId: Long,
    val name: String,
    val age: Int
)

@Entity
data class Library(
    @PrimaryKey val libraryId: Long,
    val userOwnerId: Long
)

Java

@Entity
public class User {
    @PrimaryKey public long userId;
    public String name;
    public int age;
}

@Entity
public class Library {
    @PrimaryKey public long libraryId;
    public long userOwnerId;
}

エンティティをクエリする

ユーザーと対応するライブラリのリストをクエリするには、最初に 2 つのエンティティ間の 1 対 1 のリレーションをモデル化する必要があります。

このために、親エンティティのインスタンスと子エンティティの対応するインスタンスを保持する新しいデータクラスを作成します。@Relation アノテーションを子エンティティのインスタンスに追加します。このとき、parentColumn を親エンティティの主キー列の名前に設定し、entityColumn を親エンティティの主キーを参照する子エンティティの列の名前に設定します。

Kotlin

data class UserAndLibrary(
    @Embedded val user: User,
    @Relation(
         parentColumn = "userId",
         entityColumn = "userOwnerId"
    )
    val library: Library
)

Java

public class UserAndLibrary {
    @Embedded public User user;
    @Relation(
         parentColumn = "userId",
         entityColumn = "userOwnerId"
    )
    public Library library;
}

最後に、親エンティティと子エンティティをペアにするデータクラスのすべてのインスタンスを返すメソッドを DAO クラスに追加します。このメソッドでは Room に 2 つのクエリを実行させる必要があります。したがって、このメソッドに @Transaction アノテーションを追加する必要があります。これにより、オペレーション全体がアトミックに実行されます。

Kotlin

@Transaction
@Query("SELECT * FROM User")
fun getUsersAndLibraries(): List<UserAndLibrary>

Java

@Transaction
@Query("SELECT * FROM User")
public List<UserAndLibrary> getUsersAndLibraries();