Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ / /

定义 Realm 对象模式 - Flutter SDK

在此页面上

  • 创建模型
  • 导入 Realm
  • 创建生成的文件部分指令
  • 创建 RealmModel
  • 生成 RealmObject
  • 在应用程序中使用 RealmObject
  • 将模式与 Device Sync 一起使用
  • 支持的数据类型
  • 属性注解
  • 定义关系属性
  • 将模型或类映射到其他名称
  • 对非结构化数据进行建模
  • 生成 RealmObject
  • 定义非对称对象

重要

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 中对象类型之间的关系

1

在文件顶部导入 Realm SDK 包。

schemas.dart
import 'package:realm/realm.dart';
schemas.dart
import 'package:realm_dart/realm.dart';
2

在版本 v 2.0.0中进行了更改: 生成的文件名为.realm.dart ,而不是.g.dart

添加部分指令,将第 4 步中生成的 RealmObject 文件包含在与当前处理文件相同的数据包中。

schemas.dart
part 'schemas.realm.dart';
3

为您的Realm模式创建模型。您必须包含注解 RealmModel 位于类定义的顶部。

您将在第 4 步中使用 RealmModel 生成整个应用程序中使用的公共 RealmObject

可以将模型设为私有或公开。我们建议将所有模型设为私有并在单个文件中进行定义。在类名前面加上下划线 (_),将其设为私有。

如果需要跨多个文件定义模式,可以将 RealmModel 设为公开。在名称前面添加美元符号 ($) 以公开模型。必须执行此操作才能从 RealmModel 生成 RealmObject,如第 4 步中所述。

将字段添加到 RealmModel。您可以添加所有支持的数据类型。使用属性注解包含其他行为。

schemas.dart
@RealmModel()
class _Car {
@PrimaryKey()
late ObjectId id;
late String make;
late String? model;
late int? miles;
}

注意

类名不得超过 57 个 UTF-8 字符。

4

在版本 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
5

使用上一步在应用程序中生成的 RealmObject。由于您将生成的文件作为在第 2 步中定义 RealmModel 的同一数据包的一部分包含在内,因此通过使用 RealmModel 导入文件来访问 RealmObject

myapp.dart
import './schemas.dart';
final hondaCivic = Car(ObjectId(), 'Honda', model: 'Civic', miles: 99);

App Services 模式是有效对象模式的列表,每个模式定义应用可以保留的对象类型。Realm 中的所有同步对象都必须符合 App Services 模式。

客户端应用程序在打开 Realm 时提供对象模式。如果 Realm 已包含数据,则它已具有模式,并且当打开该 Realm 时,它会根据现有模式验证客户端上的模式。

可以通过以下方式定义 App Services 模式:

在模式中,必须将 MapTo("_id") 注解与 RealmModel 中的主键结合使用,才能成功将对象模式与 App Services 同步。

@RealmModel()
class _SyncSchema {
@PrimaryKey()
@MapTo("_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 模式名称。

@RealmModel()
@MapTo('naval_ship')
class _Boat {
@PrimaryKey()
late ObjectId id;
late String name;
late int? maxKnots;
late int? nauticalMiles;
}
class _Vehicle {
@PrimaryKey()
late ObjectId id;
late String? maybeDescription; // optional value
late double milesTravelled = 0; // 0 is default value
@Ignored()
late String notInRealmModel;
@Indexed()
late String make;
@MapTo('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元素的RealmListRealmMap集合。 请注意, RealmValue不能表示RealmSet或嵌入式对象。

示例,在对变量事件日志对象建模时,您可以使用包含混合数据映射的RealmValue

数据模型
// Define class with a `RealmValue` property
@RealmModel()
class _EventLog {
@PrimaryKey()
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)

提示

  • 当类型未知但每个值都有唯一标识符时,请使用混合数据类型的映射。

  • 当类型未知但对象的顺序有意义时,请使用混合数据类型的列表。

在版本 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 定义文件的部分指令中。

schemas.dart
// ...import packages
part 'schemas.realm.dart';
@RealmModel()
// ...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()

@RealmModel(ObjectType.asymmetricObject)
class _WeatherSensor {
@PrimaryKey()
@MapTo("_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

后退

模型数据