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


Realm(Java)數據庫使用文檔(目錄)

通過繼承RealmObject基類來創建Realm模型:

public class User extends RealmObject {

    private String          name;
    private int             age;

    @Ignore
    private int             sessionId;

    // IDE生成的標準getters和setters…
    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 int    getSessionId() { return sessionId; }
    public void   setSessionId(int sessionId) { this.sessionId = sessionId; }
}

Realm model字段支持public、protected和private修飾符以及自定義方法。

public class User extends RealmObject {

    public String name;

    public boolean hasLongName() {
      return name.length() > 7;
    }

    @Override
    public boolean equals(Object o) {
      // Custom equals comparison
    }
}

3.1 字段類型

Realm支持boolean、byte、short、int、long、float、double、String、Datebyte[]字段類型。數值類型byte、short、intlong在Realm中都映射爲long。除了這些標準字段類型之外,Realm還支持RealmObjectRealmList <? extends RealmObject>擴展爲模型關係。

裝箱的Boolean、Byte、Short、Integer、Long、 FloatDouble也可以在模型類中使用。這些類型的值可能爲null

3.2 必填字段

@Required註解可用於標記Realm字段中禁止爲空值,使其成爲必填字段,而不是可選字段。 使用@Required只能註釋Boolean、Byte、Short、Integer、Long、Float、Double、String、byte[]Date。 如果將其添加到其他字段類型,編譯將失敗。

具有基本類型和RealmList類型的字段是非必需的。RealmObject類型的字段始終可以爲空。

3.3 主鍵

使用@PrimaryKey註解將字段標記爲model的主鍵。字段類型必須是字符串(String)或整數(byte, short、int、long、Byte、Short、IntegerLong)。 使用字符串字段作爲主鍵會自動爲該字段建立索引:字符串上的@PrimaryKey註解隱式設置了@Index註解。Realm不支持複合鍵,即使用多個字段作爲單個主鍵。

使用主鍵可以使用copyToRealmOrUpdate()insertOrUpdate()方法。它們查找具有給定主鍵的對象,然後更新它(如果具有該鍵的對象已經存在)或創建它(如果鍵不存在)。如果在沒有主鍵的類上調用copyToRealmOrUpdate()insertOrUpdate(),則會引發異常。

當您使用主鍵時,讀取(查詢)會稍微快一些,但是寫入(創建和更新對象)會慢一些。 性能上的變化將取決於Realm數據集的大小。

請注意,Realm.createObject返回一個新對象,其所有字段均設置爲其默認值。 如果對象是具有主鍵的類,則可能會產生衝突(可能已經存在具有該主鍵集的對象)。 爲避免這種情況,您可以創建一個非託管對象,設置其字段值,然後使用copyToRealm()insert()將其添加到Realm:

final MyObject obj = new MyObject();
obj.setId(42);
obj.setName("Fish");
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        // 在Realm中創建一個新對象,或者如果該對象已經存在(相同的主鍵),則拋出異常。

        // 更新具有相同主鍵的現有對象,或者如果沒有主鍵的對象= 42,則創建一個新對象
        realm.copyToRealmOrUpdate(obj);
    }
});

除非@PrimaryKey@Required註解結合使用,否則String類型或裝箱的整數(Byte,Short,IntegerLong)的主鍵可以具有null值。

3.4 索引屬性

要爲字段建立索引,請像主鍵一樣使用@Index註解。這會使寫入速度稍慢,但會使讀取速度更快。(存儲索引也會使您的Realm文件略大)最好僅在針對特定情況優化讀取性能時才添加索引。

可以String、byte、short、int、long、booleanDate字段使用索引。

3.5 忽略屬性

如果您不想將model中的字段保存到Realm,請使用註解@Ignore。例如,如果您的輸入包含比model更多的字段,並且您不想有很多特殊情況來處理這些未使用的數據字段,則可以這樣做。

標記爲statictransient的字段始終被忽略,並且不需要@Ignore註解。

3.6 計數器Counters

Realm提供MutableRealmInteger作爲特殊的整數類型。 MutableRealmInteger公開了一個附加API,可以在使用同步Realms時更清楚地表達意圖並生成更好的衝突解決步驟。

傳統上,將通過讀取一個值,對其進行遞增並設置它來實現計數器(myObj.counter + = 1)。 在異步情況下(例如,當兩個客戶端脫機時),不能好好工作,因爲雙方將讀取一個值,例如10,對其進行遞增,然後將該值存儲爲11。最終,當他們重新獲得連接並嘗試合併其值時 更改後,他們將同意計數器位於11而不是預期的12。

MutableRealmIntegers由傳統的整數類型支持,因此將字段從byte、short、intlong更改爲MutableRealmInteger時不需要遷移。

MutableRealmInteger不是像Java中的原始數字類型那樣的不可變類型標準。 它是一個實時對象,例如RealmObject,RealmResultsRealmList。這意味着寫入Realm時,MutableRealmInteger內部包含的值可以更改。 因此,必須將MutableRealmInteger字段標記爲final

public class Party extends RealmObject {
    public final MutableRealmInteger guests = MutableRealmInteger.valueOf(0);
}

要更改計數器值,只需調用counter.increment()counter.decrement()

Party party = realm.where(Party.class).findFirst();
realm.beginTransaction();
party.guests.get(); // 0
party.guests.increment(1); // 1
party.guests.decrement(1); // 0
party.guests.increment(5); // 5
party.guests.decrement(1); // 4
realm.commitTransaction();

要重置計數器,可以使用counter.set()爲它分配一個新值。

調用set()可能會覆蓋來自其他設備increment()和decrement()操作。正常的最後合併寫入成功,因此僅在有損計數器可接受的情況下才應進行這些操作的混合。

Party party = realm.where(Party.class).findFirst();
realm.beginTransaction();
party.guests.set(0);
realm.commitTransaction();

3.7 覆蓋屬性名稱

默認行爲是Realm將使用model類中定義的名稱作爲名稱來表示Realm文件內部的類和字段。 在某些情況下,您可能想要更改此行爲:

  • 支持具有同一項目但位於不序包中的兩個model類。
  • 爲了簡化跨平臺架構的使用,因爲命名約定不同。
  • 要使用比Realm強制使用的57個字符的限制長的Java類名。
  • 在Java中更改字段名稱而不會強制應用程序用戶完成遷移過程。

在這些情況下,可以使用@RealmModule,@RealmClass@RealmField註解定義其他名稱,以覆蓋內部使用的名稱。

您可以在module定義命名策略,這將影響module的所有類部分:

@RealmModule(
  allClasses = true, 
  classNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES,
  fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES
)
public class MyModule {
  
}

您可以爲該類定義自定義名稱,或者可以定義將影響該類中所有字段的字段命名策略。 這將覆蓋所有module級別的設置:

@RealmClass(name = "__Person", fieldNamingPolicy = RealmNamingPolicy.PASCAL_CASE)
public class Person extends RealmObject {
  public String name;  
}

您可以爲字段定義自定義名稱,這將覆蓋所有Class類和Module模塊級別的設置:

public class extends RealmObject {
  @RealmField(name = "person_name") 
  public String name;  
}

選擇與Java模型類中使用的名稱不同的內部名稱具有以下含義:

  • DynamicRealm上的查詢必須使用內部名稱。 普通Realm實例上的查詢必須繼續使用Java類中定義的名稱。
  • 創建類和字段時,遷移必須使用內部名稱。
  • 報告的架構錯誤將使用內部名稱。

請注意,更改內部名稱不會影響從JSON導入數據。 JSON數據仍必須遵循Realm Java類中定義的名稱。

在使用Moshi,GSON或Jackson之類的標準庫解析JSON時,請務必記住這些庫定義了從JSON到Java的轉換,同時設置了內部Realm名稱也定義了從Java到Realm文件的轉換。這意味着如果您想使用這些庫將數據從JSON導入Realm,則仍然需要提供JSON解析器庫和Realm的註釋。

使用Moshi,它看起來像這樣:

public class Person extends RealmObject {
    @Json(name = "first_name") // JSON輸入中使用的名稱。
    @RealmField(name = "first_name") // Realm文件內部使用的名稱。
    public string firstName; // Java中使用的名稱
}

有關更多信息,請參見RealmNamingPolicy

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章