関係 - Java SDK
関係
Realm を使用すると、アプリ内のオブジェクトのタイプ間の明示的な関係を定義できます。 関係は、プリミティブ データ型の 1 つではなく、別の Realm オブジェクトを参照するオブジェクト プロパティです。 関係を定義するには、 プロパティ スキーマでオブジェクト プロパティのタイプを別のオブジェクトタイプに設定します。
関係は Realm 内の他のオブジェクトへの直接参照であるため、関係データベースとは異なり、関係を定義するためにブリッジ テーブルや明示的な結合は必要ありません。 代わりに、関係を定義するプロパティへの読み取りと書き込みにより、関連オブジェクトにアクセスできます。 Realm は読み取り操作を入力時に遅延して実行するため、関係のクエリは通常のプロパティを読み取るのと同じ程度のパフォーマンスです。
オブジェクト間の関係には、次の 3 つのプライマリ タイプがあります。
次のタイプを使用して、オブジェクト スキーマ内の関係、コレクション、および埋め込みオブジェクトを定義できます。
RealmObject
RealmList <? extends RealmObject>
特定のフィールドが外部キー関係を表すか、埋め込みオブジェクト関係を表すかを示すには、 注釈 を使用します。 詳細については、「関係の注釈 」を参照してください。
対 1 の関係
対 1 の関係とは、あるオブジェクトが 1 つの他のオブジェクトのみに特定の方法で関連付けられていることを意味します。 タイプが関連する Realm オブジェクトタイプであるプロパティを指定することにより、オブジェクト スキーマ内のオブジェクトタイプの 1 対 1 の関係を定義します。
関係フィールドを null に設定するとオブジェクト間の接続が削除されますが、Realm は参照先のオブジェクトが埋め込まれていない限り、そのオブジェクトを削除しません。
対多の関係
対多の関係とは、オブジェクトが複数のオブジェクトに特定の方法で関連していることを意味します。 タイプRealmList<T>
のフィールドを使用して、1 つのオブジェクトと任意の数のオブジェクトとの間の関係を作成できます。ここでは、 T
はアプリケーション内の Realm オブジェクトです。
逆の関係
逆の関係は、定義された 1 対多または 1 多の関係でオブジェクトを参照する他のオブジェクトにオブジェクトをリンクします。 関係の定義は一方向であるため、オブジェクトのモデルでプロパティを逆の関係として明示的に定義する必要があります。
たとえば、「ユーザーは多数のタスクを持っている」という対多の関係では、「タスクはユーザーに属する」という逆関係は自動的に作成されません。 オブジェクトモデルで逆の関係を指定しない場合は、特定のタスクに割り当てられているユーザーを検索するために別のクエリを実行する必要があります。
逆の関係を定義するには、オブジェクトモデルでLinkingObjects
プロパティを定義します。 LinkingObjects
定義は、反転する関係のオブジェクトタイプとプロパティ名を指定します。
Realm は、指定された関係内でオブジェクトが追加または削除されるたびに、暗黙的な関係を自動的に更新します。 逆関係プロパティの値を手動で設定することはできません。
@LinkingObjects
で注釈が付けられたフィールドは次の条件を満たす必要があります。
マーク
final
型
RealmResults<T>
の で、T
は関係の反対側にある型
関係は多対 1 または多対多であるため、次の逆の関係がある場合は、ゼロ、1、または多のオブジェクトが生成されます。
他のRealmResults
セットと同様に、逆関係をクエリできます。
関係フィールドの定義
警告
修飾可能なフィールドのアアクセスとミューテーションを常に定義する
Realm オブジェクトは getter と setter を使用して、アップデートされたフィールド値を Realm に永続化します。 アップデートには常に getter と setter を使用してください。
多対 1
多対 1 または 1 対 1 の関係を設定するには、アプリケーション内に Realm オブジェクトであるタイプのフィールドを作成します。
import io.realm.RealmObject; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private Frog bestFriend; public Frog(String name, int age, String species, String owner, Frog bestFriend) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.bestFriend = bestFriend; } public Frog(){} // RealmObject subclasses must provide an empty constructor public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } public Frog getBestFriend() { return bestFriend; } public void setBestFriend(Frog bestFriend) { this.bestFriend = bestFriend; } }
import io.realm.RealmObject open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null var bestFriend: Frog? = null constructor( name: String?, age: Int, species: String?, owner: String?, bestFriend: Frog? ) { this.name = name this.age = age this.species = species this.owner = owner this.bestFriend = bestFriend } constructor() {} // RealmObject subclasses must provide an empty constructor }
重要
対 1 の関係は任意である必要があります
オブジェクトモデルで 1 の関係を宣言する場合、それは任意の プロパティである必要があります。 対 1 の関係を必要にしようとすると、Realm は実行時に例外をスローします。
各Frog
は、0 件のFrog
インスタンスまたは 1 つのその他のFrog
インスタンスを参照します。 複数のFrog
インスタンスが同じFrog
をベストプラクティスとして参照することを妨げるものではありません。多対 1 と 1 対 1 の関係の区別はアプリケーションによって異なります。
Many-toMany
import io.realm.RealmList; import io.realm.RealmObject; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private RealmList<Frog> bestFriends; public Frog(String name, int age, String species, String owner, RealmList<Frog> bestFriends) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.bestFriends = bestFriends; } public Frog(){} // RealmObject subclasses must provide an empty constructor public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } public RealmList<Frog> getBestFriends() { return bestFriends; } public void setBestFriends(RealmList<Frog> bestFriends) { this.bestFriends = bestFriends; } }
import io.realm.RealmList import io.realm.RealmObject open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null var bestFriends: RealmList<Frog>? = null constructor( name: String?, age: Int, species: String?, owner: String?, bestFriends: RealmList<Frog>? ) { this.name = name this.age = age this.species = species this.owner = owner this.bestFriends = bestFriends } constructor() {} // RealmObject subclasses must provide an empty constructor }
RealmList
はRealmObject
のコンテナですが、それ以外の場合は通常のコレクションと同様に動作します。 複数のRealmList
で同じオブジェクトを使用できます。
逆の関係
デフォルトでは、Realm の関係は一方向であり、 あるクラスから参照されたクラスへのリンクを追跡できますが、逆方向へのリンクはありません。 frogFriends
のリストを持つToad
を定義する次のクラスを考えてみましょう。
import io.realm.RealmList; import io.realm.RealmObject; public class Toad extends RealmObject { private RealmList<Frog> frogFriends; public Toad(RealmList<Frog> frogFriends) { this.frogFriends = frogFriends; } public Toad() {} public RealmList<Frog> getFrogFriends() { return frogFriends; } public void setFrogFriends(RealmList<Frog> frogFriends) { this.frogFriends = frogFriends; } }
import io.realm.RealmList import io.realm.RealmObject open class Toad : RealmObject { var frogFriends: RealmList<Frog>? = null constructor(frogFriends: RealmList<Frog>?) { this.frogFriends = frogFriends } constructor() {} }
RealmResults<T>
タイプのfinal
(Java )またはval
( Kotlin )フィールドに@LinkingObjectsアノテーションを使用して、 Frog
からToad
までの逆方向のリンクを提供できます。
import io.realm.RealmObject; import io.realm.RealmResults; import io.realm.annotations.LinkingObjects; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private final RealmResults<Toad> toadFriends = null; public Frog(String name, int age, String species, String owner) { this.name = name; this.age = age; this.species = species; this.owner = owner; } public Frog(){} // RealmObject subclasses must provide an empty constructor public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSpecies() { return species; } public void setSpecies(String species) { this.species = species; } public String getOwner() { return owner; } public void setOwner(String owner) { this.owner = owner; } }
import io.realm.RealmObject import io.realm.RealmResults import io.realm.annotations.LinkingObjects open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null private val toadFriends: RealmResults<Toad>? = null constructor(name: String?, age: Int, species: String?, owner: String?) { this.name = name this.age = age this.species = species this.owner = owner } constructor() {} // RealmObject subclasses must provide an empty constructor }
重要
逆関係フィールドはfinal
でマークする必要があります。