Realm オブジェクトモデルの定義 - Java SDK
項目一覧
Realm オブジェクトの定義
アプリケーションで Realm オブジェクトを定義するには、 RealmObjectのサブクラスを作成するか、RealmModel を実装します。
重要
すべての Realm オブジェクトは空のコンストラクターを提供する必要があります。
すべての Realm オブジェクトでは、Java では
public
可視性修飾子または Kotlin ではopen
可視性修飾子を使用する必要があります。
注意
クラス名は最大 57 文字の UTF-8 文字に制限されています。
拡張 RealmObject
次のコード ブロックは、Fros を記述する Realm オブジェクトを示しています。 この Fros クラスは、 RealmObject
クラスをextends
であるため、Realm に保存できます。
import io.realm.RealmObject; // To add an object to your Realm Schema, extend RealmObject public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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 // providing default values for each constructor parameter // fulfills the need for an empty constructor open class Frog( var name: String? = null, var age: Int = 0, var species: String? = null, var owner: String? = null ) : RealmObject() // To add an object to your Realm Schema, extend RealmObject
実装 RealmModel
次のコード ブロックは、Fros を記述する Realm オブジェクトを示しています。 この Flow クラスは、 RealmModel
クラスをimplements
し、 @RealmClass
アノテーションを使用しているため、Realm に保存できます。
import io.realm.RealmModel; import io.realm.annotations.RealmClass; public class Frog implements RealmModel { private String name; private int age; private String species; private String owner; 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; } }
重要
すべての Realm オブジェクトはpublic
可視性修飾子を使用する必要があります。
import io.realm.RealmModel import io.realm.annotations.RealmClass open class Frog : RealmModel { var name: String? = null var age = 0 var species: String? = null var owner: String? = 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 }
重要
すべての Realm オブジェクトはopen
可視性修飾子を使用する必要があります。
Tip
RealmObject メソッドの使用
RealmObject
クラスを拡張して Realm オブジェクトを作成すると、Realm オブジェクトのインスタンスでRealmObject
クラスのメソッドに動的にアクセスできます。 RealmModel
を実装して作成された Realm オブジェクトは、 RealmObject
クラスを介して同じメソッドに静的にアクセスできます。
// With RealmObject frogRealmObject.isValid(); frogRealmObject.addChangeListener(listener); // With RealmModel RealmObject.isValid(frogRealmModel); RealmObject.addChangeListener(frogRealmModel, listener);
// With RealmObject frogRealmObject?.isValid frogRealmObject?.addChangeListener(listener) // With RealmModel RealmObject.isValid(frogRealmModel) RealmObject.addChangeListener(frogRealmModel, listener)
リスト
Realm オブジェクトには、非 Realm オブジェクト データ型のリストを含めることができます。
Realm オブジェクトのリストとは異なり、これらのリストには null 値を含めることができます。 null 値が許可されない場合は、 @Required注釈を使用します。
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<String> favoriteColors; public Frog(String name, int age, String species, String owner, RealmList<String> favoriteColors) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.favoriteColors = favoriteColors; } 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<String> getFavoriteColors() { return favoriteColors; } public void setFavoriteColors(RealmList<String> favoriteColors) { this.favoriteColors = favoriteColors; } }
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 favoriteColors : RealmList<String>? = null constructor( name: String?, age: Int, species: String?, owner: String?, favoriteColors: RealmList<String>? ) { this.name = name this.age = age this.species = species this.owner = owner this.favoriteColors = favoriteColors } constructor() {} // RealmObject subclasses must provide an empty constructor }
埋め込みオブジェクト フィールドの定義
Realm では、他の オブジェクト内にオブジェクトをネストする機能が提供されます。 これには、次のような利点があります。
Sync を使用する場合、オブジェクトは非正規化されたデータモデルに従う MongoDB ドキュメントに変換されます。
別のオブジェクトを含むオブジェクトを削除すると、削除操作によって両方のオブジェクトが Realm から削除されるため、未使用のオブジェクトが Realm ファイルに蓄積されることはなく、ユーザーのモバイル デバイス上の有効なスペースを占有することになります。
オブジェクトを埋め込むには、別のクラス内にネストするクラスで、 @RealmClassアノテーションのembedded
プロパティをtrue
に設定します。
import io.realm.RealmObject; import io.realm.annotations.RealmClass; public class Fly extends RealmObject { private String name; public Fly(String name) { this.name = name; } public Fly() {} // RealmObject subclasses must provide an empty constructor }
import io.realm.RealmObject import io.realm.annotations.RealmClass open class Fly : RealmObject { private var name: String? = null constructor(name: String?) { this.name = name } constructor() {} // RealmObject subclasses must provide an empty constructor }
その後、そのクラスを別のクラスから参照するたびに、Realm は次の例のように、参照されたクラスを囲む クラス内に埋め込まれます。
import io.realm.RealmObject; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; private Fly lastMeal; public Frog(String name, int age, String species, String owner, Fly lastMeal) { this.name = name; this.age = age; this.species = species; this.owner = owner; this.lastMeal = lastMeal; } 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 Fly getLastMeal() { return lastMeal; } public void setLastMeal(Fly lastMeal) { this.lastMeal = lastMeal; } }
import io.realm.RealmObject open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = null var lastMeal: Fly? = null constructor( name: String?, age: Int, species: String?, owner: String?, lastMeal: Fly? ) { this.name = name this.age = age this.species = species this.owner = owner this.lastMeal = lastMeal } constructor() {} // RealmObject subclasses must provide an empty constructor }
注釈
Realm オブジェクトモデルをカスタマイズするには、注釈を使用します。
プライマリキー
バージョン 10.6.0 の新機能: Realm はプライマリキー フィールドを自動的にインデックス化します。 以前は、Realm はString
プライマリキーのみを自動的にインデックス化していました。
Realm は、 @PrimaryKeyアノテーションでマークされたフィールドを、対応するオブジェクト スキーマのプライマリキーとして扱います。 プライマリキーには、次の制限が適用されます。
オブジェクト スキーマごとに定義できるプライマリキーは 1 つだけです。
プライマリキー値は、Realm 内のオブジェクトのすべてのインスタンスで一意である必要があります。 重複するプライマリキー値を挿入しようとすると、 RealmPrimaryKeyConstorageException が発生します。
プライマリキーの値は不変です。 オブジェクトのプライマリキー値を変更するには、元のオブジェクトを削除し、別のプライマリキー値を持つ新しいオブジェクトを挿入する必要があります。
埋め込みオブジェクトではプライマリキーを定義できません。
次のいずれかのタイプのプライマリキーを作成できます。
String
UUID
ObjectId
Integer
orint
Long
orlong
Short
orshort
Byte
orbyte[]
非プライマリ タイプにはプライマリキー値としてnull
の値を含めることができますが、各プライマリキー値は一意である必要があるため、特定のタイプの 1 つのオブジェクトにのみ含まれます。 既存のプライマリキーを持つオブジェクトを Realm に挿入しようとすると、 RealmPrimaryKeyConstorageException が発生します。
Realm はプライマリキー フィールドを自動的にインデックス化します。これにより、プライマリキーに基づいてオブジェクトを効率的に読み取り、変更できます。
オブジェクトタイプのプライマリキー フィールドは、そのタイプのオブジェクトを Realm に追加した後では、変更できません。 Sync を使用している場合、バックエンドスキーマでプライマリキーを定義した後、オブジェクトのプライマリキー フィールドを変更することはできません。
埋め込みオブジェクトにはプライマリキーを含めることはできません。
オプションで、 @PrimaryKey 注釈を使用して、 オブジェクト スキーマ の一部としてオブジェクト タイプのプライマリキーを定義できます。
import io.realm.RealmObject; import io.realm.annotations.PrimaryKey; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.PrimaryKey open class Frog : RealmObject { var name : String? = null var age = 0 var species: String? = null var owner: String? = 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 }
必須 フィールド
import io.realm.RealmObject; import io.realm.annotations.Required; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.Required open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = 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 }
任意 フィールド
Java オブジェクト型 と Kotlin nullable 型( ?
で終了)でマークされたフィールドは、デフォルトで null 可能です。 他のすべてのタイプ(プリミティブ、null 以外の Kotlin オブジェクトタイプ)はデフォルトで必要です。 null 可能なフィールドを@Requiredアノテーションでマークして、そのフィールドが null 値を保持しないようにできます。 Realmlistは null 不可能ですが、基本型で null が許可されている場合でも、 @Required
アノテーションを使用してリスト内のオブジェクトが null 値を保持するのを防ぐことができます。 RealmObject
サブタイプのRealmList
を必須としてマークすることはできません。
次のいずれかのタイプを必須にすることができます。
String
UUID
ObjectId
Integer
Long
Short
Byte
orbyte[]
Boolean
Float
Double
Date
RealmList
int
やRealmList
型などのプリミティブ型は暗黙的に必要です。 RealmObject
型のフィールドは常に null 可能であり、必須にすることはできません。
重要
Kotlin の型と null 可能性
Kotlin では、型に?
サフィックスを明示的に追加しない限り、型はデフォルトで null 以外です。 注釈はnull 可能な型のみです。 null 以外の型で@Required
アノテーションを使用すると、コンパイルが失敗します。
Realmでは、 @Required注釈で特に指定されていない限り、null フィールドはデフォルトで任意です。 次の型は null 可能です。
String
Date
UUID
ObjectId
Integer
Long
Short
Byte
orbyte[]
Boolean
Float
Double
int
やlong
のようなプリミティブ型は、デフォルトで null 以外であり、null 値に設定できないため、null 可能にすることはできません。
デフォルトのフィールド値
フィールドにデフォルト値を割り当てるには、組み込み言語機能を使用してデフォルト値を割り当てます。
デフォルト値を割り当てするには、 クラス コンストラクターを使用します。
import io.realm.RealmObject; public class Frog extends RealmObject { private String name = "Kitty"; private int age; private String species; private String owner; 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 open class Frog : RealmObject { var name = "Kitty" var age = 0 var species: String? = null var owner: String? = 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 }
注意
デフォルト値と null 可能性
デフォルト値により、新しく作成されたオブジェクトにnull
の値を含めることはできませんが(デフォルト値としてnull
を指定しない限り)、フィールドの null 可能性には影響しません。 フィールドを null 以外にするには、「必須フィールド 」を参照してください。
フィールドのインデックス
インデックスは、Realm でクエリを効率的に実行するのに役立ちます。 インデックスがない場合、Realm はコレクションスキャンを実行する必要があります。つまり、コレクション内のすべてのドキュメントをスキャンして、クエリに一致するドキュメントを選択する必要があります。 クエリに適切なインデックスがある場合、Realm はそのインデックスを使用して検査する必要があるドキュメントの数を制限できます。
インデックスは、Realm のデータのごく一部を簡単に走査できる形式で保存する特別なデータ構造です。 インデックスには、特定のフィールドの値が、フィールド値の順に保存されます。 インデックス エントリの順序付けは、効率的な等価一致と範囲ベースのクエリ操作をサポートします。
インデックスを追加すると、一部のクエリは高速化されますが、書込み時間がわずかに遅くなり、ストレージとメモリのオーバーヘッドが増加します。 インデックスには Realm ファイル内にスペースが必要になるため、プロパティにインデックスを追加すると、Realm ファイルで消費されるディスク容量が増えます。 各インデックスエントリは 12 バイト以上です。
次のタイプのフィールドをインデックスできます。
String
UUID
ObjectId
Integer
orint
Long
orlong
Short
orshort
Byte
orbyte[]
Boolean
orbool
Date
RealmAny
Realm は@Index で注釈が付けられたフィールドのインデックスを作成します。
フィールドにインデックスを付けるには、 @Index注釈 を使用します。
import io.realm.RealmObject; import io.realm.annotations.Index; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.Index open class Frog : RealmObject { var name: String? = null var age = 0 var species : String? = null var owner: String? = 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 }
フィールドを無視
モデル内のフィールドを Realm に保存したくない場合は、フィールドを無視できます。
@Ignore注釈を使用して Realm オブジェクト モデルのフィールドを無視します。
import io.realm.RealmObject; import io.realm.annotations.Ignore; public class Frog extends RealmObject { private String name; private int age; private String species; // can you ever really own a frog persistently? private String owner; 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.annotations.Ignore open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null // can you ever really own a frog persistently? var owner : String? = 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 }
注意
SDK は静的フィールドと一時的なフィールドを無視します
static
またはtransient
とマークされたフィールドは常に無視されるため、 @Ignore
アノテーションは必要ありません。
フィールド名の変更
デフォルトでは、Realm はモデル クラスで定義された名前を使用して内部フィールドを表します。 場合によっては、この動作を変更する必要があるかもしれません。
命名規則が異なるプラットフォーム間での操作を容易にするため。
移行を強制せずに Kotlin でフィールド名を変更するには。
モデル クラスで使用される名前とは異なる内部名を選択する場合、次の影響があります。
移行では、クラスとフィールドを作成するときに内部名を使用する必要があります。
報告されたスキーマ エラーでは内部名が使用されます。
フィールドの名前を変更するには、 @RealmFieldアノテーションを使用します。
import io.realm.RealmObject; import io.realm.annotations.RealmField; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.RealmField open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = 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 }
あるいは、モジュール レベルまたはクラス レベルで命名ポリシーを割り当てて、Realm がフィールド名を解釈する方法を変更することもできます。
モジュール レベル で 命名ポリシー を定義できます。これは、モジュールに含まれるすべてのクラスに影響します。
import io.realm.annotations.RealmModule; import io.realm.annotations.RealmNamingPolicy; public class MyModule { }
import io.realm.annotations.RealmModule import io.realm.annotations.RealmNamingPolicy open class MyModule
クラス レベルで命名ポリシーを定義することもできます。これは、モジュール レベルの設定を上書きします。
import io.realm.RealmObject; import io.realm.annotations.RealmClass; import io.realm.annotations.RealmNamingPolicy; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.RealmClass import io.realm.annotations.RealmNamingPolicy open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = 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 }
クラス名の変更
デフォルトでは、Realm はモデル クラスで定義された名前を使用して内部クラスを表します。 場合によっては、この動作を変更する必要があるかもしれません。
異なるパッケージで同じ単純名を持つ複数のモデル クラスをサポートします。
命名規則が異なるプラットフォーム間での操作を容易にするため。
Realm によって強制される 57 文字の制限よりも長いクラス名を使用します。
移行を強制せずに Kotlin でクラス名を変更します。
クラスの名前を変更するには、 @RealmClassアノテーションを使用します。
import io.realm.RealmObject; import io.realm.annotations.RealmClass; public class Frog extends RealmObject { private String name; private int age; private String species; private String owner; 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.annotations.RealmClass open class Frog : RealmObject { var name: String? = null var age = 0 var species: String? = null var owner: String? = 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 }
Realm スキーマからクラスを省略する
デフォルトでは、アプリケーションの Realm スキーマにはRealmObject
を拡張するすべてのクラスが含まれます。 Realm スキーマにRealmObject
を拡張するクラスのサブセットのみを含める場合は、そのクラスのサブセットをモジュールに含め、そのモジュールを使用して Realm を開きます。
import io.realm.annotations.RealmModule; public class MyModule { }
import io.realm.annotations.RealmModule open class MyModule