关系 - Java SDK
关系
Realm允许您定义应用中对象类型之间的显式关系。 关系是引用另一个Realm 对象而不是某一原始数据类型的对象属性。 您可以通过将对象属性的类型设置为属性模式中的另一种对象类型来定义关系。
关系是对 Realm 中其他对象的直接引用,这意味着您不需要像在关系数据库中那样使用桥接表或显式联接来定义关系。相反,您可以通过读取和写入定义关系的属性来访问相关对象。Realm 会延迟执行读取操作,因此查询关系与读取常规属性一样有效。
对象之间主要有三种关系:
您可以使用以下类型在对象模式中定义关系、集合和嵌入式对象:
RealmObject
RealmList <? extends RealmObject>
使用注解来指示给定字段表示外键关系还是嵌入式对象关系。 有关更多信息,请参阅关系注解。
对一关系
对一关系是指一个对象以特定方式与不超过一个其他对象相关。您可以通过指定属性(其中该类型是相关 Realm 对象类型)来为对象模式中的对象类型定义对一关系。
将关系字段设置为 null 将删除对象之间的连接,但 Realm 不会删除引用的对象,除非该对象为嵌入式对象。
对多关系
对多关系是指一个对象以特定方式与多个对象相关。您可以使用类型为 RealmList<T>
的字段在一个对象与任意数量的其他对象之间创建关系,其中 T
是应用程序中的 Realm 对象:
反向关系
反向关系将对象链接回在定义的对一或对多关系中引用该对象的任何其他对象。关系定义是单向的,因此必须在对象模型中明确将属性定义为反向关系。
例如,对多关系“User has many Tasks”不会自动创建反向关系“Task belongs to User”。 如果不在对象模型中指定反向关系,就需要运行单独的查询来查找分配给某个任务的用户。
要定义反向关系,请在对象模型中定义一个 LinkingObjects
属性。LinkingObjects
定义指定了反向关系的对象类型和属性名称。
每当在指定关系中添加或删除对象时,Realm都会自动更新隐式关系。无法手动设置反向关系属性的值。
用 @LinkingObjects
注释的字段必须是:
已标记
final
类型为
RealmResults<T>
,其中T
是关系另一端的类型
由于关系是多对一或多对多,因此,遵循反向关系可能会得到零个、一个或多个对象。
与其他任何RealmResults
集合一样,您可以查询反向关系。
定义关系字段
警告
始终为可修改字段定义访问器和修改器
Realm 对象使用 getter 和 setter 将更新的字段值保存到 Realm。始终使用 getter 和 setter 进行更新。
多对一
要设置多对一或一对一关系,请在应用程序中创建一个类型为 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 }
重要
对一关系必须是可选的
在对象模型中声明对一关系时,它必须是一个可选属性。如果您尝试建立所需的对一关系,Realm 会在运行时引发异常。
每个 Frog
可引用零个 Frog
实例或一个其他 Frog
实例。没有什么可以阻止多个 Frog
实例将引用同一 Frog
作为好友;多对一和一对一关系之间的区别取决于您的应用程序。
多对多
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() {} }
您可以在相反方向上提供从Frog
到Toad
的链接,方法是在final
(在 Java 中)或val
(在 Kotlin 中)类型为RealmResults<T>
的字段上使用@LinkingObjects注解:
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
。