Realm(Java)数据库使用文档(目录)
您可以将任何两个RealmObject链接在一起。在Realm中关系很轻便:遍历链接在速度或内存方面并不占用过多资源。让我们探索一下Realm允许您在对象之间进行定义的不同类型的关系。
5.1 多对一
要建立“多对一”或“一对一”关系,请给model一个属性,其类型是您的RealmObject子类之一:
public class Email extends RealmObject {
private String address;
private boolean active;
}
public class Contact extends RealmObject {
private String name;
private Email email;
}
Contact bob = realm.createObject(Contact.class);
bob.name = "Bob Newhart";
Email email1 = realm.createObject(Email.class);
email1.address = "[email protected]";
bob.email = email1;
每个联系人具有零个或一个电子邮件实例。没有什么可以阻止您将同一个电子邮件对象与多个联系人一起使用;多对一关系和一对一关系之间的区别取决于您的业务逻辑。
将关系字段设置为null将清除引用:
bob.email = null;
这将删除bob和email1之间的关系,但是email1仍在Realm中。
5.2 多对多
您可以通过RealmList <T>
字段声明从单个对象创建与任何数量的对象的关系。 让我们重写示例以支持多个电子邮件地址:
public class Contact extends RealmObject {
public String name;
public RealmList<Email> emails;
}
public class Email extends RealmObject {
public String address;
public boolean active;
}
RealmLists是RealmObjects的容器;RealmList的行为类似于常规的Java List。您可以在不同的RealmLists中使用同一对象,并且可以使用该对象对“一对多”和“多对多”关系进行建模。
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Contact contact = realm.createObject(Contact.class);
contact.name = "John Doe";
Email email1 = realm.createObject(Email.class);
email1.address = "[email protected]";
email1.active = true;
contact.emails.add(email1);
Email email2 = realm.createObject(Email.class);
email2.address = "[email protected]";
email2.active = false;
contact.emails.add(email2);
}
});
可以声明递归关系,这在对某些类型的数据建模时很有用。
public class Person extends RealmObject {
public String name;
public RealmList<Person> friends;
// 其他字段...
}
将RealmList字段的值设置为null将清除列表。列表将为空(长度为零),但列表中的对象不会从Realm中删除。RealmList的getter永远不会返回null:返回的对象始终是列表。长度可能为零。
5.3 逆关系
关系是单向的。 以Person和Dog这两个类为例:
public class Dog extends RealmObject {
private String name;
private int age;
}
public class Person extends RealmObject {
@PrimaryKey
private long id;
private String name;
private RealmList<Dog> dogs;
}
您可以点击从“人”到“狗”的链接,但是无法从“狗”到其“人”对象。 您可以通过为Dog提供@LinkingObjects注解来解决此问题。
public class Person extends RealmObject {
private String id;
private String name;
private RealmList<Dog> dogs;
// getters and setters
}
public class Dog extends RealmObject {
private String id;
private String name;
private String color;
@LinkingObjects("dogs")
private final RealmResults<Person> owners;
// getters and setters
}
我们为Dog提供了一个所有者字段,并指定该字段应包含在其dogs字段中具有此Dog对象的所有Person对象。
带注解的字段必须声明为final
,并且必须为RealmResults <T>
类型,其中T是关系相对端的类型/类。由于关系是多对一或多对多的,因此遵循逆向关系可能会导致0、1或更多对象。
像任何其他RealmResults
集一样,您可以查询逆关系。
5.4 基元列表(Lists Of Primitives)
Realm Model类可以包含原始数据类型的列表。 这必须使用RealmList <T>
进行建模,其中T可以是以下类型:String, Integer, Boolean, Float, Double, Short, Long, Byte, byte[]
和Date
。
public class Person extends RealmObject {
public String name;
public RealmList<String> children = new RealmList<>();
}
与RealmModel
的列表不同,基元列表可以包含空值。如果不允许使用空值,请使用@Required
注解:
public class Person extends RealmObject {
public String name;
@Required
public RealmList<String> children = new RealmList<>();
}
基元列表不支持列表列表和查询。
在Realm Java 4.0.0之前,通常使用特殊的Realm <String / Int>
类对基元列表进行建模。您可以使用以下迁移代码从此方法迁移到基元列表:
// Model classes
public class RealmString extends RealmObject {
public String value;
}
public class Person extends RealmObject {
public String name;
@Required
public RealmList<String> children = new RealmList<>();
}
// Migration code
RealmObjectSchema objSchema = realmSchema.get("Person");
objSchema.addRealmListField("children_tmp", String.class)
.setRequired("children_tmp", true)
.transform(new RealmObjectSchema.Function() {
@Override
public void apply(DynamicRealmObject obj) {
RealmList<DynamicRealmObject> children = obj.getList("children");
RealmList<String> migratedChildren = obj.getList("children_tmp", String.class);
for (DynamicRealmObject child : children) {
migratedChildren.add(child.getString("value"));
}
}
})
.removeField("children")
.renameField("children_tmp", "children");