本页介绍可用于定义对象模型中的属性的受支持数据类型。有关如何定义对象模型的更多信息,请参阅定义对象模型。
BSON types要学习;了解如何将特定数据类型映射到App Services模式中的 ,请参阅 Atlas App Services文档中的 数据模型映射 。
支持的数据类型列表
Kotlin SDK支持以下Kotlin类型 、 BSON 类型和 Realm 特定类型,这些类型可用于唯一标识符、时间戳、计数器和集合。
Kotlin SDK 原生不支持:
用户定义的枚举属性。有关如何在 Realm 对象中使用枚举的更多信息,请参阅枚举部分。
Kotlin 的内置
Date或Instant。有关如何在 Realm 对象中使用时间戳的更多信息,请参阅 RealmInstant 部分。
Realm 对象属性必须是可变的,并在声明时初始化。Kotlin SDK 当前不支持抽象属性。您可以使用内置 ? Kotlin 操作符将属性声明为可选(可为 null),也可以在声明属性时为其分配默认值。
注意
Realm 将所有非十进制数值类型存储为 Long 值,将所有十进制数值类型存储为 Double 值。
Kotlin 数据类型
下表列出支持的 Kotlin 数据类型,以及如何在对象模型中将它们声明为必选或可选属性的示例。
Kotlin 数据类型 | 必需 | Optional | ||
|---|---|---|---|---|
| | | ||
| | | ||
| | | ||
| | | ||
| | | ||
| | | ||
| | | ||
| | | ||
| | |
MongoDB BSON 类型
下表列出了支持的MongoDB BSON数据类型,以及如何在对象模型中将其声明为必填或可选属性的示例。要使用这些类型,您必须从org.mongodb.kbson包中导入它们。
MongoDB BSON 类型 | 必需 | Optional | ||
|---|---|---|---|---|
| | |||
| | |
特定 Realm 类型
下表列出支持的 Realm 特有数据类型,以及如何在对象模型中将它们声明为必选或可选属性的示例。
Realm 特定类型 | 必需 | Optional | ||
|---|---|---|---|---|
| | |||
| | |||
不适用 | | |||
| | |||
| 不适用 | |||
| 不适用 | |||
| 不适用 | |||
不适用 | | |||
不适用 | |
Unique Identifiers
Kotlin SDK支持将 UUID 和 ObjectId 作为Realm对象的唯一标识符。
注意
使用 UUID 而不是 ObjectId
通常,您可将 UUID 用于用作唯一标识符的任意字段。如果要迁移未存储在 MongoDB 中的数据,使用 UUID 可能非常有用,这是因为对象的唯一标识符可能已是 UUID 类型。或者,对于 MongoDB 中已存在的数据集合,使用 ObjectId 可能非常有用。
ObjectId
ObjectId 是 MongoDB 特有的 BSON 类型。它是一个 12 字节的全局唯一值,可用作对象的标识符。它可以为 null、可以索引、可以用作主键。
您可以使用 ObjectId() 初始化 ObjectId。
重要
io.realm.kotlin.types.ObjectId 在 v1.5.0 中已弃用
在Realm Kotlin SDK版本 1.5.0 及更高版本中,io.realm.kotlin.types.ObjectId 已弃用。您必须改为从 org.mongodb.kbson.ObjectId 导入 ObjectId。
RealmUUID
UUID (通用唯一标识符)是一个 16 字节的唯一值,可用作对象的标识符。它可以为 null、可索引、并可用作主键。
Realm创建符合 RFC4122 版本4 并使用随机字节创建的 RealmUUID 类型的UUID。
您可以使用RealmUUID.random()生成随机RealmUUID 或将 UUID 格式的string传递给RealmUUID.from():
val uuid1 = RealmUUID.from("46423f1b-ce3e-4a7e-812f-004cf9c42d76") val uuid2 = RealmUUID.random()
MutableRealmInt(计数器)
Kotlin SDK提供MutableRealmInt 作为特殊整数类型,您可以将其用作逻辑计数器,以跨多个分布式客户端准确同步数字更改。其行为类似于Long ,但还支持实现无冲突复制数据类型的increment 和decrement 方法。这可确保无论顺序如何,都可以执行数值更新以收敛到相同的值。
MutableRealmInt 属性:
不能用作主键
不能存储空值,但可以声明为可空 (
MutableRealmInt?)。
此外,MutableRealmInt 字段:
由 Kotlin 的数值类型支持,因此将数值字段更改为
MutableRealmInt时无需迁移。可以使用类似于
Long提供的操作符和中缀函数。但请注意,除set、increment和decrement之外的任何操作都不会更改执行这些操作的实例。相反,他们会使用更新后的值创建一个新的非托管MutableRealmInt实例。
RealmInstant(时间戳)
您不能在 Realm 中存储 Kotlin 内置的 Date 或 Instant 类型。
相反,Kotlin SDK 会使用 RealmInstant 类型将时间信息存储为 Unix 纪元 时间戳。
如果需要 RealmInstant 以外形式的时间戳数据,可以根据以下示例在模型类中添加转换代码:
// model class that stores an Instant (kotlinx-datetime) field as a RealmInstant via a conversion class RealmInstantConversion : RealmObject { private var _timestamp: RealmInstant = RealmInstant.from(0, 0) public var timestamp: Instant get() { return _timestamp.toInstant() } set(value) { _timestamp = value.toRealmInstant() } } fun RealmInstant.toInstant(): Instant { val sec: Long = this.epochSeconds // The value always lies in the range `-999_999_999..999_999_999`. // minus for timestamps before epoch, positive for after val nano: Int = this.nanosecondsOfSecond return if (sec >= 0) { // For positive timestamps, conversion can happen directly Instant.fromEpochSeconds(sec, nano.toLong()) } else { // For negative timestamps, RealmInstant starts from the higher value with negative // nanoseconds, while Instant starts from the lower value with positive nanoseconds // TODO This probably breaks at edge cases like MIN/MAX Instant.fromEpochSeconds(sec - 1, 1_000_000 + nano.toLong()) } } fun Instant.toRealmInstant(): RealmInstant { val sec: Long = this.epochSeconds // The value is always positive and lies in the range `0..999_999_999`. val nano: Int = this.nanosecondsOfSecond return if (sec >= 0) { // For positive timestamps, conversion can happen directly RealmInstant.from(sec, nano) } else { // For negative timestamps, RealmInstant starts from the higher value with negative // nanoseconds, while Instant starts from the lower value with positive nanoseconds // TODO This probably breaks at edge cases like MIN/MAX RealmInstant.from(sec + 1, -1_000_000 + nano) } }
RealmAny(混合)
在版本2.0.0中进行了更改: RealmAny可以保存混合数据的列表和字典。
RealmAny表示不可为空的混合数据类型。 其行为与其包含的值类型相同。 RealmAny可以保存:
支持的Kotlin数据类型(请注意,
Byte、Char、Int、Long和Short值会在内部转换为int64_t值)RealmList和RealmDictionary混合数据集合以下特定 Realm 类型:
RealmInstant
RealmUUID
RealmObject(保存对象的引用,而不是其副本)
RealmAny 不能保存EmbeddedRealmObject类型、 RealmSet或其他RealmAny 。
RealmAny 属性:
必须声明为可空 (
RealmAny?),但不能存储空值可以使用 RealmQuery.max 进行 聚合 ,RealmQuery.min和RealmQuery.sum。
可以进行排序。从最高到最低的排序顺序如下:
BooleanByte,Double,Decimal128,Int,Float,Long,Shortbyte[],StringDateObjectIdUUIDRealmObject
您可以在 RealmList、RealmDictionary 或 RealmSet 字段中存储多个 RealmAny 实例。
提示
使用条件表达式处理多态性
因为您必须知道存储的类型才能提取其值,所以我们建议使用 when 表达式来处理 RealmAny 类型及其可能的内部值类。
混合集合
在版本2.0.0及更高版本中, RealmAny数据类型可以保存RealmAny元素的集合(列表或字典,但不是设立)。 您可以使用混合集合对非结构化或可变数据进行建模。 有关更多信息,请参阅定义非结构化数据。
您最多可以嵌套100级混合集合。
您可以查询混合集合属性并注册变更监听器,就像查询普通集合一样。
您可以查找并更新单个混合集合元素
不能在混合集合中存储集合或嵌入式对象。
要在应用中使用混合集合,请在数据模型中定义混合类型属性,就像定义任何其他RealmAny类型一样。 然后,使用RealmAny.create()创建列表或字典集合。
集合类型
Kotlin SDK 提供了几种集合类型,您可以将其用作数据模型中的属性。集合是包含受支持数据类型的零个或多个实例的对象。Realm 集合是同质的(集合中的所有对象类型相同),并由相应的内置 Kotlin 类支持。
集合类型是非空的。定义集合属性时,必须对其初始化。有关更多信息,请参阅“创建集合”。
RealmList
RealmList 类型实现了 Kotlin 的 List 接口。非托管列表的行为类似于 Kotlin 的MutableList。
RealmList 表示对多关系,包含:
RealmList<E> 是非 null 类型,其中:
包含
RealmObject或EmbeddedRealmObject元素的列表不能为空任何其他受支持的元素列表可以为 null (
RealmList<E?>)
RealmSet
RealmSet 类型实现了 Kotlin 的 Set 接口。非托管集的行为类似于 Kotlin 的MutableSet。
RealmSet 表示对多关系,包含以下不同值:
不能在 RealmSet 中使用 EmbeddedRealmObject 元素。
RealmSet<E> 是非 null 类型,其中:
RealmObject元素集不能为 null任何其他受支持的元素集可以为 null (
RealmSet<E?>)
RealmMap/RealmDictionary
RealmMap 类型实现了 Kotlin 的 Map 接口,是一个包含具有唯一键的键值String 对的关联大量。RealmDictionary 是一种特殊的 RealmMap,它接受 String 键和非字符串值。非托管字典的行为类似于 Kotlin 的LinkedHashMap。
RealmDictionary 值可以是:
RealmDictionary<K, V> 是非 null 类型,其中:
键必须是字符串
RealmObject或EmbeddedRealmObject值必须可以为 null (RealmDictionary<K, V?>)任何其他支持的元素值都可以为空
RealmObjects 作为属性
您可以在对象模型中使用 RealmObject 和除 AsymmetricRealmObject 以外的任何子类作为属性。
重要
AsymmetricRealmObject 不能用作属性。有关详细信息,请参阅非对称对象。
RealmObject
RealmObject类型表示可用作属性的自定义对象。
RealmObject 属性:
必须声明为 nullable
可以用作集合中的元素
可以作为
RealmAny值保存不能用作主键
您还可以通过对一和对多关系从另一个 Realm 引用一个或多个 Realm 对象。有关更多信息,请参阅关系页面。
反向链接
反向链接表示 RealmObject 和一个或多个 RealmObject 之间或 RealmObject 和 EmbeddedRealmObject 之间的反向多对多关系。反向链接不能为空。
反向链接实现:
RealmObject反向链接的BacklinksDelegate类型EmbeddedRealmObject反向链接的EmbeddedBacklinksDelegate类型
有关详细信息,请参阅反向关系。
EmbeddedRealMobject
EmbeddedRealmObject是一种特殊类型的RealmObject 。
EmbeddedRealmObject 属性:
必须是父对象中的可空对象
必须是字典中可为 null 的值
列表中的元素不能为空
不能用作主键
可以是不对称对象中的属性
有关详细信息,请参阅嵌入式对象。
地理空间类型
1.11.0 版本中的新增功能。
Kotlin SDK 支持使用以下数据类型进行地理空间查询:
重要
无法保留地理空间数据类型
目前,地理空间数据类型无法持久化。例如,您不能声明类型为 GeoBox 的属性。
这些类型只能用作地理空间查询的参数。
有关使用地理空间数据进行查询的更多信息,请参阅地理空间数据。
Enums
Kotlin SDK 本身不支持枚举。要在 Realm 对象类中使用枚举,请定义一个类型与枚举的底层数据类型匹配的字段。
然后,为该字段创建 getter 和 setter,以在底层值和枚举类型之间转换字段值。
enum class EnumClass(var state: String) { NOT_STARTED("NOT_STARTED"), IN_PROGRESS("IN_PROGRESS"), COMPLETE("COMPLETE") } class EnumObject : RealmObject { var name: String? = null private var state: String = EnumClass.NOT_STARTED.state var stateEnum: EnumClass get() = EnumClass.valueOf(state) set(value) { state = value.state } }