オブジェクトモデルの変更 - Java SDK
次の例は、スキーマ内でプロパティを追加、削除、および変更する方法を示しています。 まず、必要なスキーマを変更します。 次に、スキーマのバージョンを増やします。 最後に、変更が重大的(破壊的)な場合は、元のスキーマから更新されたスキーマにデータを移動するための対応する移行関数を作成します。
注意
Realm Open でのバージョン更新
次の例に示す各スキーマの変更は、アプリケーションが既存のスキーマを使用した後に発生するとします。 新しいスキーマのバージョン番号は、Realm を開き、新しいバージョン番号を明示的に指定した後にのみ適用されます。 つまり、以前にバージョン0 、 1 、 2を指定して使用していた場合を除き、バージョン3を指定することはできません。
スキーマ バージョン 0
を使用する Realm のオブジェクトタイプはPerson
です。
public class Person extends RealmObject { // Realm schema version 0 public String firstName; public int age; }
class Person: RealmObject { // Realm schema version 0 var firstName: String = "" var age: int = 0 }
A. プロパティを追加する
次の例では、元の Response スキーマにlastName
プロパティを追加しています。
public class Person extends RealmObject { // Realm schema version 1 public String firstName; public String lastName; public int age; }
class Person: RealmObject { // Realm schema version 1 var firstName: String = "" var lastName: String = "" var age: int = 0 }
B. プロパティを削除する
次の例では、元の people スキーマの個別のfirstName
プロパティとlastName
プロパティではなく、結合されたfullName
プロパティを使用します。
public class Person extends RealmObject { // Realm schema version 2 public String fullName; public int age; }
class Person: RealmObject { // Realm schema version 2 var fullName: String = "" var age: int = 0 }
C. プロパティタイプを変更またはプロパティの名前を変更
次の例では、名前をbirthday
に変更し、 タイプをDate
に変更することで、元の Python スキーマのage
プロパティを変更します。
public class Person extends RealmObject { // Realm schema version 3 public String fullName; public Date birthday = new Date(); }
class Person: RealmObject { // Realm schema version 3 var fullName: String = "" var birthday: Date = Date() }
D. 移行関数
更新されたPerson
スキーマに準拠するように Realm を移行するには、Realm のスキーマ バージョンを3
に設定し、既存のfirstName
とlastName
プロパティに基づいてfullName
の値を設定するための移行関数を定義します。 age
に基づくbirthday
の値:
public class Migration implements RealmMigration { public void migrate(DynamicRealm realm, long oldVersion, long newVersion) { Long version = oldVersion; // DynamicRealm exposes an editable schema RealmSchema schema = realm.getSchema(); // Changes from version 0 to 1: Adding lastName. // All properties will be initialized with the default value "". if (version == 0L) { schema.get("Person") .addField("lastName", String.class, FieldAttribute.REQUIRED); version++; } // Changes from version 1 to 2: combine firstName/lastName into fullName if (version == 1L) { schema.get("Person") .addField("fullName", String.class, FieldAttribute.REQUIRED) .transform( DynamicRealmObject obj -> { String name = "${obj.getString("firstName")} ${obj.getString("lastName")}"; obj.setString("fullName", name); }) .removeField("firstName") .removeField("lastName"); version++; } // Changes from version 2 to 3: replace age with birthday if (version == 2L) { schema.get("Person") .addField("birthday", Date::class.java, FieldAttribute.REQUIRED) .transform(DynamicRealmObject obj -> { Int birthYear = Date().year - obj.getInt("age"); obj.setDate("birthday", Date(birthYear, 1, 1)); }) .removeField("age"); version++; } } }; public class Module {} RealmConfiguration config = new RealmConfiguration.Builder() .modules(new Module()) .schemaVersion(3) // Must be bumped when the schema changes .migration(new Migration()) // Migration to run instead of throwing an exception .build();
val migration = object: RealmMigration { override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { var version: Long = oldVersion // DynamicRealm exposes an editable schema val schema: RealmSchema = realm.schema // Changes from version 0 to 1: Adding lastName. // All properties will be initialized with the default value "". if (version == 0L) { schema.get("Person")!! .addField("lastName", String::class.java, FieldAttribute.REQUIRED) version++ } // Changes from version 1 to 2: Combining firstName/lastName into fullName if (version == 1L) { schema.get("Person")!! .addField("fullName", String::class.java, FieldAttribute.REQUIRED) .transform { obj: DynamicRealmObject -> val name = "${obj.getString("firstName")} ${obj.getString("lastName")}" obj.setString("fullName", name) } .removeField("firstName") .removeField("lastName") version++ } // Changes from version 2 to 3: Replace age with birthday if (version == 2L) { schema.get("Person")!! .addField("birthday", Date::class.java, FieldAttribute.REQUIRED) .transform { obj: DynamicRealmObject -> var birthYear = Date().year - obj.getInt("age") obj.setDate("birthday", Date(birthYear, 1, 1)) } .removeField("age") version++ } } } class Module val config = RealmConfiguration.Builder() .schemaVersion(3) // Must be bumped when the schema changes .migration(migration) // Migration to run instead of throwing an exception .build()
アプリケーションのバックエンドで定義されているJSON schema を変更することで、同期された Realm のスキーマを変更できます。 同期された Realm には移行関数は必要ありません。同期されたスキーマへの重大な変更は同期エラーの原因となるためです。 同期は、同期された Realm スキーマへの重大でない変更を自動的に処理します。 その結果、ユーザーがアプリケーションをアップグレードする際に、スキーマの古いバージョンと新しいバージョンの両方が同期できます。
同期された Realm へのスキーマ変更の詳細については、「同期されたスキーマの変更 」を参照してください。
注意
開発モード: 初期スキーマの定義のみ
開発モードを使用して、アプリケーションの同期されたスキーマの最初のバージョンを定義できます。これにより、バックエンドでクライアント モデルがJSON schemaに自動的に変換されます。 ただし、アプリ内の JSON schema を編集して、スキーマに後続の変更を加える必要があります。
Tip
RealmConfiguration.ShouldDeleteRealmIfMigrationNeted()を使用できます ビルダ メソッドを使用して、移行が必要な場合に移行を実行する代わりにRealmを削除するRealmを構築します。 これは、開発中にスキーマが頻繁に変更される場合に便利です。