Realm(Java)數據庫使用文檔(Relationships)


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");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章