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");