定义 Realm 对象模式 - Flutter SDK
在此页面上
重要
Flutter SDK v 2.0.0 对生成文件的重大更改
Flutter SDK版本2.0.0 引入了对构建器的更新,这会影响文件的生成方式。 在 v 2.0.0及更高版本中,所有生成的文件都使用 .realm.dart
命名规范,而不是.g.dart
。
对于现有应用程序来说,这是一项破坏性变更 (breaking change)。 有关如何升级现有应用从早期 SDK 版本升级到2.0.0或更高版本的信息,请参阅升级到Flutter SDK v 2.0.0 。
对象模式是定义 Realm 对象属性和关系的配置对象。Realm 客户端应用程序使用“Object Schema”(对象模式),以相应的语言通过原生类实现来定义对象模式。
对象模式指定对对象属性的约束,例如每个属性的数据类型以及是否需要属性。模式还可以定义 Realm 中对象类型之间的关系。
创建模型
创建 RealmModel
为您的Realm模式创建模型。您必须包含注解 RealmModel 位于类定义的顶部。
您将在第 4 步中使用 RealmModel
生成整个应用程序中使用的公共 RealmObject
。
可以将模型设为私有或公开。我们建议将所有模型设为私有并在单个文件中进行定义。在类名前面加上下划线 (_
),将其设为私有。
如果需要跨多个文件定义模式,可以将 RealmModel 设为公开。在名称前面添加美元符号 ($
) 以公开模型。必须执行此操作才能从 RealmModel
生成 RealmObject
,如第 4 步中所述。
将字段添加到 RealmModel
。您可以添加所有支持的数据类型。使用属性注解包含其他行为。
()class _Car { () late ObjectId id; late String make; late String? model; late int? miles; }
注意
类名不得超过 57 个 UTF-8 字符。
生成 RealmObject
在版本 v 2.0.0中进行了更改: 生成的文件名为.realm.dart
,而不是.g.dart
生成将在应用程序中使用的 RealmObject
(Realm 对象):
dart run realm generate
dart run realm_dart generate
此命令在与模型文件相同的目录中生成文件。它具有您在第 2 步的部分指令中指定的名称。
提示
跟踪生成的文件
在 git 等版本控制系统中跟踪生成的文件。
例子
生成模型后的文件结构
. ├── schemas.dart ├── schemas.realm.dart // newly generated file ├── myapp.dart └── ...rest of application
将模式与 Device Sync 一起使用
App Services 模式是有效对象模式的列表,每个模式定义应用可以保留的对象类型。Realm 中的所有同步对象都必须符合 App Services 模式。
客户端应用程序在打开 Realm 时提供对象模式。如果 Realm 已包含数据,则它已具有模式,并且当打开该 Realm 时,它会根据现有模式验证客户端上的模式。
可以通过以下方式定义 App Services 模式:
使用 App Services 显式定义 App Services 模式。
在模式中,必须将 MapTo("_id")
注解与 RealmModel
中的主键结合使用,才能成功将对象模式与 App Services 同步。
()class _SyncSchema { () "_id") ( late ObjectId id; // ... other properties }
有关定义模式以及应考虑将哪些方法用于应用程序的更多信息,请参阅创建 Realm 模式文档。
支持的数据类型
Realm 模式支持许多 Dart 语言数据类型,此外还有一些 Realm 特定类型。要全面了解所有支持的数据类型,请参阅数据类型。
属性注解
使用注解为 Realm 对象模型中的属性添加功能。可以使用注解来执行将属性标记为可为空、设置主键、忽略属性等操作。要进一步了解可用的属性注解,请参阅属性注解。
定义关系属性
可以定义模式中 Realm 对象之间的关系。Realm Flutter SDK 支持一对一关系、一对多关系、反向关系以及将对象嵌入其他对象中。要详细了解如何在 Realm 对象模式中定义关系,请参阅关系。
将模型或类映射到其他名称
您可以使用 MapTo 注解将 Realm 对象模型或属性映射到 Realm 中存储的不同名称。这在以下场景中非常有用。例如:
要便于在具有不同命名约定的多个平台上工作。例如,如果 Device Sync 模式属性名称使用蛇形大小写,而项目使用驼峰大小写。
在不强制迁移的情况下更改类名或字段名。
支持不同数据包中的多个同名模型类。
要使用长度大于 Realm 执行的 57 个字符限制的类名。
如果使用的是 Atlas Device Sync,则在 MapTo
注解中指定的名称用作持久的 App Services 模式名称。
()'naval_ship') (class _Boat { () late ObjectId id; late String name; late int? maxKnots; late int? nauticalMiles; }
class _Vehicle { () late ObjectId id; late String? maybeDescription; // optional value late double milesTravelled = 0; // 0 is default value () late String notInRealmModel; () late String make; 'wheels') // 'wheels' is property name in the RealmObject ( late int numberOfWheels; }
对非结构化数据进行建模
2.0.0版本新增。
从Flutter SDK版本2.0.0开始, 您可以在RealmValue
属性中存储混合数据的集合。 您可以使用此功能对复杂的数据结构(例如JSON或MongoDB文档)进行建模,而无需定义严格的数据模型。
非结构化数据是指不容易符合预期模式的数据,因此对单个数据类进行建模很困难或不切实际。 示例,您的应用可能具有高度可变的数据或动态数据,其结构在运行时未知。
将集合存储在混合属性中可在不牺牲功能的情况下提供灵活性,包括使用Device Sync时的性能同步。 您可以像使用非混合集合一样使用它们:
您最多可以嵌套100级混合集合。
您可以对混合集合的React进行查询和响应。
您可以查找并更新单个混合集合元素。
但是,与使用结构化模式或将JSON blob 序列化为单个string属性相比,在混合集合中存储数据的性能较低。
要对应用中的非结构化数据进行建模,请在模式中将相应属性定义为RealmValue类型。 然后,您可以设立这些RealmValue
属性设置为RealmValue
元素的RealmList或RealmMap集合。 请注意, RealmValue
不能表示RealmSet
或嵌入式对象。
示例,在对变量事件日志对象建模时,您可以使用包含混合数据映射的RealmValue
:
// Define class with a `RealmValue` property ()class _EventLog { () late ObjectId id; late String eventType; late DateTime timestamp; late String userId; late RealmValue details; }
realm.write(() { // Add `eventLog` property data as a map of mixed data, which // also includes nested lists of mixed data realm.add(EventLog(ObjectId(), 'purchase', DateTime.now(), 'user123', details: RealmValue.from({ 'ipAddress': '192.168.1.1', 'items': [ {'id': 1, 'name': 'Laptop', 'price': 1200.00}, {'id': 2, 'name': 'Mouse', 'price': 49.99} ], 'total': 1249.99 }))); final eventLog = realm.all<EventLog>().first; final items = eventLog.details.asMap(); print(''' Event Type: ${eventLog.eventType} Timestamp: ${eventLog.timestamp} User ID: ${eventLog.userId} Details: Item: '''); for (var item in items.entries) { print('${item.key}: ${item.value}'); }
Event Type: purchase Timestamp: 2024-03-18 13:50:58.402979Z User ID: user123 Details: Item: ipAddress: RealmValue(192.168.1.1) items: RealmValue([RealmValue({id: RealmValue(1), name: RealmValue(Laptop), price: RealmValue(1200.0)}), RealmValue({id: RealmValue(2), name: RealmValue(Mouse), price: RealmValue(49.99)})]) total: RealmValue(1249.99)
提示
当类型未知但每个值都有唯一标识符时,请使用混合数据类型的映射。
当类型未知但对象的顺序有意义时,请使用混合数据类型的列表。
生成 RealmObject
在版本 v 2.0.0中进行了更改: 生成的文件名为.realm.dart
,而不是.g.dart
完成 Realm 模型后,您必须生成 RealmObject 类才能在应用程序中进行使用。
运行以下命令以生成 RealmObjects
:
dart run realm generate
dart run realm_dart generate
运行此命令会在您根据“创建模型”部分定义RealmModel
类的目录中的新文件中创建一个公共类。
生成的文件与带有 RealmModel
的文件具有相同的基本名称,以 .realm.dart
结尾。例如,如果带有 RealmModel
的文件名为 schemas.dart
,则生成的文件将为 schemas.realm.dart
。
注意
请记住将生成的文件包含在 RealmModel
定义文件的部分指令中。
// ...import packages part 'schemas.realm.dart'; ()// ...model definition
如果您希望观察数据模型在发生更改时生成 RealmObjects
,请在命令中包含 --watch
标志。
dart run realm generate --watch
dart run realm_dart generate --watch
要清理生成器缓存,请在命令中加入 --clean
标志。进行调试时,清理生成器缓存可能很有用。
dart run realm generate --clean
dart run realm_dart generate --clean
定义非对称对象
版本 1.5.0 新增内容。
非对称对象需要灵活同步。要定义非对称对象,请将 ObjectType.asymmetricObject
传递给 @RealmModel()
。
(ObjectType.asymmetricObject)class _WeatherSensor { () "_id") ( late ObjectId id; late String deviceId; late double modtemperatureInFahrenheitel; late double barometricPressureInHg; late double windSpeedInMph; }
在 Flutter SDK 版本 1.5.0 及更早版本中,您无法从 asymmetricObject
类型链接到 RealmObjects
。在 SDK 版本 1.6.0 及更高版本中,除了嵌入式对象类型外,asymmetricObject
类型还可以链接到 RealmObjects
。
注意
尝试读取非对称对象
无法读取非对称对象。如果尝试查询非对称对象,您将收到以下错误:“错误:无法查询非对称类。”
要了解有关数据导入的更多信息,请参阅将数据流式传输到 Atlas。