定义 Realm 对象模型 - Kotlin SDK
在此页面上
本页介绍了Realm 对象类型以及如何将Realm对象定义为应用程序数据模型的一部分。 定义对象模型后,您可以打开域具有包含您定义的对象的模式的 Realm,并在该域中使用它们。
Kotlin SDK内存将Realm对象直接映射到原生Kotlin对象,因此无需使用特殊的数据访问库。 您可以通过应用程序代码对象中声明的常规Kotlin类来定义应用程序的数据模型。
要学习;了解如何在定义Realm 对象模型后更改Realm对象,请参阅更改对象模型。
注意
使用Device Sync定义数据模型
如果您的应用使用Atlas Device Sync,则在定义数据模型时还需要注意其他事项。 有关更多信息,请参阅使用Device Sync对数据进行建模 - Kotlin SDK。
RealmObject
Realm对象是具有唯一命名的Kotlin类实例,您可以像使用任何其他类实例一样使用它们。
每个对象类代表一个对象类型。 同一类型的对象股票一个对象模式,该模式定义该类型对象的属性和关系。 SDKACID 一致性保证域的所有对象都符合其对象类型的模式,并在创建、修改或删除对象时验证对象。
但请注意,Realm 对象具有以下限制:
Realm 对象必须继承自
RealmObject
类或其子类:EmbeddedRealmObject
或AsymmetricRealmObject
。 Kotlin SDK不支持从自定义基类继承。Kotlin SDK要求Realm对象具有空的构造函数。 请参阅下一节中提到的解决方法示例。
类名不得超过 57 个 UTF-8 字符。
此外, Kotlin SDK 不 支持使用Kotlin 数据类 对数据进行建模。这是因为数据类通常用于不可变数据,这违背了Realm Kotlin SDK对数据进行建模的方式。
定义新对象类型
要定义新的对象类型,您必须创建一个具有唯一名称的Kotlin类,该类实现RealmObject
、 EmbeddedRealmObject
或AsymmetricRealmObject
接口。
注意
类名不得超过 57 个 UTF-8 字符。
然后,指定对象的属性,包括:
每个属性的数据类型。 Kotlin SDK 支持以下数据类型:
BSON 的有限子集 类型
Realm 特定类型,可用于唯一标识符、时间戳、计数器和集合
任何属性注解,可为Realm对象中的属性添加功能。 您可以使用注解:
将属性指定主键
将属性标记为可索引
忽略属性
将属性或类名称映射到另一个名称
与其他Realm对象的任何关系。
定义Realm 对象模型后,您可以在域Realm 时将对象类设立传递给 Realm 的配置,然后在域中处理这些对象。
重要
Realm需要一个空的构造函数
Realm Kotlin SDK不支持使用单个主构造函数。 SDK 需要一个空的构造函数来创建对象。 作为一种解决方法,您可以执行类似于以下操作的操作:
class Person(var name: String, var age: Int): RealmObject { constructor(): this("", 0) // Empty constructor required by Realm }
定义 Realm 对象类型
要定义 Realm 对象类型,请创建一个实现RealmObject接口的 Kotlin 类:
// Implements the `RealmObject` interface class Frog : RealmObject { // Empty constructor required by Realm var _id: ObjectId = ObjectId() var name: String = "" var age: Int = 0 var species: String? = null var owner: String? = null }
定义嵌入式对象类型
EmbeddedRealmObject
是一种特殊类型的 Realm 对象,用于对有关特定对象的复杂数据进行建模。 Realm 将每个嵌入式对象视为单个特定父对象内的嵌套数据。
因此,嵌入式对象具有以下限制:
嵌入式对象需要一个父对象,并且不能作为独立的 Realm 对象存在。 如果父对象不再引用该嵌入式对象,则该嵌入式对象将被自动删除。
嵌入式对象会继承其父对象的生命周期。 示例,如果删除父对象,则嵌入式对象也会被删除。
嵌入式对象与其父对象具有严格的所有权关系。 您不能将嵌入式对象重新分配给不同的父对象,也不能在多个父对象之间股票嵌入式对象对象。
嵌入式对象不能具有主键。
提示
如果您需要手动管理被引用对象的生命周期,或者希望被引用对象在删除父对象后仍然存在,请改用具有对一关系的常规Realm 对象。 有关更多信息,请参阅关系 - Kotlin SDK。
要定义 Realm 对象类型,请创建一个实现EmbeddedRealmObject接口的 Kotlin 类:
// Implements `EmbeddedRealmObject` interface class EmbeddedAddress : EmbeddedRealmObject { // CANNOT have primary key var street: String? = null var city: String? = null var state: String? = null var postalCode: String? = null var propertyOwner: Contact? = null }
嵌入式对象类型具有可重用性和可组合性。 您可以在其他嵌入式对象类型内的多个父对象类型中使用相同的嵌入式对象类型。
定义嵌入式对象类型后,必须在数据模型中定义与父对象的关系。 要学习;了解如何操作,请参阅定义嵌入式对象。
定义非对称对象类型
版本 1.10.0 中的新增内容。
AsymmetricRealmObject
是仅插入对象,旨在与Atlas Device Sync功能数据导入一起使用。 有关如何在应用程序中设立数据导入的信息,请参阅将数据流式传输到Atlas - Kotlin SDK。
非对称对象广泛支持与RealmObject
相同的属性类型,但存在一些例外情况:
非对称对象只能在配置了 Flexible Sync 的同步 Realm 中使用。 但是,您无法创建非对称对象的订阅。
AsymmetricRealmObject
可以包含EmbeddedRealmObject
类型,但不能包含RealmObject
类型或其他AsymmetricRealmObject
类型。AsymmetricRealmObject
类型不能用作其他 Realm 对象中的属性。
此外,不对称对象的运行方式与其他Realm对象不同。 您无法在域中添加、读取、更新或删除非对称对象。 您只能创建一个非对称对象,然后该对象会单向同步到通过Device Sync链接到您的应用的Atlas数据库。 Realm会在同步后删除该对象。
要定义非对称的 Realm 对象类型,请创建一个实现AsymmetricRealmObject接口的 Kotlin 类:
// Implements the `AsymmetricRealmObject` interface class WeatherSensor : AsymmetricRealmObject { var id: ObjectId = ObjectId() var deviceId: String = "" var temperatureInFarenheit: Float = 0.0F var barometricPressureInHg: Float = 0.0F var windSpeedInMph: Int = 0 }
在Kotlin SDK版本1.11.1及更早版本中,您无法从AsymmetricRealmObject
类型链接到RealmObject
类型。 在 SDK 版本1.12.0及更高版本中,除了EmbeddedRealmObject
类型之外, AsymmetricRealmObject
类型还可以链接到RealmObject
类型。
定义集合属性
集合是包含受支持数据类型的零个或多个实例的对象。 Realm集合是同质的(集合中的所有对象都是同一类型),并由相应的内置Kotlin类支持。 有关Kotlin SDK中使用的集合类型及其支持的数据类型的更多信息,请参阅集合类型。
Kotlin SDK提供了几种集合类型,您可以将其用作数据模型中的属性: RealmList
、 RealmSet
和RealmDictionary
。
集合还允许您定义Realm对象之间的多对多关系。 有关更多信息,请参阅关系 - Kotlin SDK 。
重要
初始化集合属性
集合类型为非空值。 定义集合属性时,必须对其进行初始化。
定义 RealmList
要将属性定义为RealmList ,请在对象模式中将其类型指定为RealmList<E>
并使用realmListOf()初始化默认值:
// RealmList<E> can be any supported primitive // or BSON type, a RealmObject, or an EmbeddedRealmObject class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // List of RealmObject type (CANNOT be nullable) var favoritePonds: RealmList<Pond> = realmListOf() // List of EmbeddedRealmObject type (CANNOT be nullable) var favoriteForests: RealmList<EmbeddedForest> = realmListOf() // List of primitive type (can be nullable) var favoriteWeather: RealmList<String?> = realmListOf() } class Pond : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" }
定义 RealmSet
要将属性定义为RealmSet ,请在对象模式中将其类型指定为RealmSet<E>
,并使用realmSetOf() 初始化默认值:
// RealmSet<E> can be any supported primitive or // BSON type or a RealmObject class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Set of RealmObject type (CANNOT be nullable) var favoriteSnacks: RealmSet<Snack> = realmSetOf() // Set of primitive type (can be nullable) var favoriteWeather: RealmSet<String?> = realmSetOf() } class Snack : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" }
定义 RealmDictionary/RealmMap
要将属性定义为RealmDictionary ,请在对象模式中将其类型指定为RealmDictionary<K, V>
并使用realmDictionaryOf()初始化默认值:
// RealmDictionary<K, V> can be any supported // primitive or BSON types, a RealmObject, or // an EmbeddedRealmObject class Frog : RealmObject { var _id: ObjectId = ObjectId() var name: String = "" // Dictionary of RealmObject type (value MUST be nullable) var favoriteFriendsByPond: RealmDictionary<Frog?> = realmDictionaryOf() // Dictionary of EmbeddedRealmObject type (value MUST be nullable) var favoriteTreesInForest: RealmDictionary<EmbeddedForest?> = realmDictionaryOf() // Dictionary of primitive type (value can be nullable) var favoritePondsByForest: RealmDictionary<String?> = realmDictionaryOf() }
Realm 不允许在映射键中使用 .
或 $
字符。您可以使用百分比编码和解码来存储包含这些不允许的任一字符的映射键。
// Percent encode . or $ characters to use them in map keys val mapKey = "Hundred Acre Wood.Northeast" val encodedMapKey = "Hundred Acre Wood%2ENortheast"
定义非结构化数据
2.0.0版本新增。
从Kotlin SDK版本2.0.0开始, 您可以在RealmAny
属性中存储混合数据的集合。 您可以使用此功能对复杂的数据结构(例如JSON或MongoDB文档)进行建模,而无需定义严格的数据模型。
非结构化数据是指不容易符合预期模式的数据,因此对单个数据类进行建模很困难或不切实际。 示例,您的应用可能具有高度可变的数据或动态数据,其结构在运行时未知。
将集合存储在混合属性中可在不牺牲功能的情况下提供灵活性,包括使用Device Sync时的性能同步。 您可以像使用非混合集合一样使用它们:
您最多可以嵌套100级混合集合。
您可以对混合集合的React进行查询和响应。
您可以查找并更新单个混合集合元素。
但是,与使用结构化模式或将JSON blob 序列化为单个string属性相比,在混合集合中存储数据的性能较低。
要对应用中的非结构化数据进行建模,请在模式中将相应属性定义为RealmAny类型。 然后,您可以设立这些RealmAny
属性设置为RealmAny
元素的RealmList或RealmDictionary集合。 请注意, RealmAny
不能表示RealmSet
或嵌入式对象。
提示
当类型未知但每个值都有唯一标识符时,请使用混合数据类型的映射。
当类型未知但对象的顺序有意义时,请使用混合数据类型的列表。