[官网文档翻译]Flutter持久化库drift - 高级特性 - 自定义数据行类
本文翻译自 drift 的 官方文档 Custom row classes (simonbinder.eu)。
肉翻多有不足,不吝赐教。
自定义数据行类
使用自定义类做为 drift 表的数据行类。
对于在 Dart 中或 drift 文件中声明的每个表, drift_dev
会生成一个(数据)行类(有时也被称为数据类),用来为更新和插入保有一个完整的数据行或其姊妹类。这能正常对应大多数情况: drift 知道表中有多少列,能为所有列生成一个简单的类。尽管如此,一些情况下,也可能想要定制生成的类。例如:想要添加一个 mixin , 用来扩展另一个类或接口,或者使用 json_serilaizable
之类的构建器来定制如何序列化成 json 。
从 moor 的4.3版本(和drift)开始,使用自定义类作为数据类。
使用自定义类
要使用自定义数据行类,只需简单地在表定义上添加注解 @UseRowClass
。
@UseRowClass(User)
class Users extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
DateTimeColumn get birthday => dateTime()();
}
class User {
final int id;
final String name;
final DateTime birthDate;
User({required this.id, required this.name, required this.birthDate});
}
一个数据行类(非自定义)必须带着以下必要项目:
- 必须有一个未命名的构造方法
- 每个构造方法参数必须有一个 drift 列的列名(匹配在表定义中的 getter 名称)
- 构造方法的参数类型必须和列的类型相同,包括是否可空和已应用的类型转换器。
另一方面,注意这些:
- 一个自定义数据行类可以有附加的字段和构造方法参数,只要它们不是 required (必需的)。 drift 在映射到数据库的行时会忽略这些参数。
- 一个表可以有未反映到自定义数据行类里的附加列。 drift 在匹配数据行时会不加载这些列。
使用另外一个构造方法
默认情况下,drift 会使用默认的、未命名的构造方法来映射一个数据行到类。如果想要使用另外一个构造方法,在 @UseRowClass
注解中设置 constructor
参数。
@UseRowClass(User, constructor: 'fromDb')
class Users extends Table {
// ...
}
class User {
final int id;
final String name;
final DateTime birthDate;
User.fromDb({required this.id, required this.name, required this.birthDate});
}
drift 文件中存在的行
要使用 drift 文件中的存在的数据行类,需要在表声明的末尾使用 WITH
关键字。也不要忘了引入声明数据行类的 Dart 文件到 drift 文件中。
import 'user.dart'; -- 或者其它 Dart 文件名
CREATE TABLE users(
id INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
birth_date DATETIME NOT NULL
) WITH User;
用自定义(数据行)类插入和更新
大多数情况下,生成的姊妹数据行类是用来更新和插入的正确工具。如果更想用自定义的数据行类来插入,只需要实现 Insertable
, T
是你的自定义数据行类自身。例如:前面的类可以改为这样:
class User implements Insertable<User> {
final int id;
final String name;
final DateTime birthDate;
User({required this.id, required this.name, required this.birthDate});
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
return UsersCompanion(
id: Value(id),
name: Value(name),
birthDate: Value(birthDate),
).toColumns(nullToAbsent);
}
}
何时使用自定义(数据行)类是明智的
drift 默认生成的类的内容对于大多数应用来说是不错的默认内容。可是在一些高级使用情况下,自定义类会是个更好的替代方案:
- 减少生成代码的大小:因为历史原因和向后兼容性, drift 类包含很多用于 json 序列化的方法和
copyWith
,这些方法并不是对所有用户都是必需的。这种情况下使用自定义数据行类可以减少代码的膨胀。 - 自定义父类:一个自定义数据行类可以用来扩展、归类和实现或者根据需要 mix-in (混入)其他类
- 其它代码生成器:因为是由你来控制(数据行)类,所以可以更好地利用其它构建器如
json_serializable
或者built_value
。
限制
这些限制会在即将来到的 drift 版本中逐渐去掉。可跟踪此 issue 查看详细内容。
现在,本特性会受以下限制影响:
- 在 drift 文件中,只能使用默认的未命名的构造方法。
- 自定义数据行类只能用表,不能用来定制编译后查询的结果集。
转载自:https://juejin.cn/post/7035999127339008013