更改对象模型 — Java SDK
以下示例演示如何在模式中添加、删除和修改属性。 首先,进行所需的模式更改。 然后,递增模式版本。 最后,如果更改是破坏性的,则创建相应的迁移函数,将数据从原始模式移动到更新后的模式。
注意
Realm Open 上的版本更新
假设以下示例中显示的每次模式更改都发生在应用程序使用现有模式之后。 仅当您打开域并显式指定新版本号后,新模式版本号才会应用。 换言之,如果事先未指定和使用版本3 0、 和 ,则无法指定版本1 2。
使用模式版本 0
的域具有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. 添加属性
以下示例将lastName
属性添加到原始 Person 模式:
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. 删除属性
以下示例使用组合的fullName
属性,而不是原始 Person 模式中单独的firstName
和lastName
属性:
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修改属性类型或重命名属性
以下示例修改了原始 Person模式中的age
属性,将其重命名为birthday
并将类型更改为Date
:
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. 迁移函数
要迁移 Realm 以符合更新的Person
模式,请将 Realm 的模式版本设置为fullName
3
并定义一个迁移函数,根据现有的firstName
和lastName
属性以及birthday
的值基于age
:
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 不需要迁移函数,因为对同步模式的重大更改会导致同步错误。 Sync 会自动处理对已同步域模式进行的非重大更改。 因此,当用户升级其应用程序时,旧版本的模式和新版本的模式都可以同步。
要学习;了解有关同步 Realm模式更改的更多信息,请参阅同步模式更改。
注意
开发模式:仅用于定义初始模式
您可以使用Development Mode定义应用程序同步模式的第一个版本,该模式会在后端自动将客户端模型转换为JSON schema。 但是,您应该通过编辑 App 中的JSON schema模式对模式进行后续更改。
提示
您可以使用RealmConfiguration.shouldDeleteRealmIfMigrationNeeded() 构建器方法,在构造域时删除该域 ,而不是在需要迁移时执行迁移。 在开发过程中,当模式经常发生变化时,这会派上用场。