如何将 SQL 视图定义为 Dart 类
摘要
如何将 SQL 视图定义为 Dart 类
你也可以将 SQL 视图 (Views) 定义为 Dart 类。要做到这一点,你需要编写一个继承自 View 的抽象类。下面的例子声明了一个视图,用于读取我们示例中添加到某个分类的待办事项数量:
dart
abstract class CategoryTodoCount extends View {
// Getter 用于定义此视图将从中读取的表。
Todos get todos;
Categories get categories;
// 可以通过将自定义表达式定义为 getter 来为其命名:
Expression<int> get itemCount => todos.id.count();
@override
Query as() =>
// 视图可以选择类上定义为表达式 getter 的列,或者
// 它们可以引用其他表中的列。
select([categories.description, itemCount]).from(categories).join([
innerJoin(todos, todos.category.equalsExp(categories.id)),
]);
}在 Dart 视图中,你可以使用:
抽象的 getter 来声明你将要读取的表 (例如
TodosTable get todos)。Expression类型的 getter 来添加列 (例如itemCount => todos.id.count())。重写的
as方法来定义支持该视图的 select 语句。select中引用的列可以是两种类型:- 视图本身定义的列 (如上例中的
itemCount)。 - 引用的其他表中定义的列 (如
categories.description)。对于这些引用,drift 的高级功能(如类型转换器)如果已在表的列定义中使用,也将应用于视图的列。
当被选中时,这两种列都将被添加到视图的数据类中。
- 视图本身定义的列 (如上例中的
最后,需要通过将视图包含在 views 参数中,将其添加到数据库或访问器中:
dart
@DriftDatabase(tables: [Todos, Categories], views: [CategoryTodoCount])
class MyDatabase extends _$MyDatabase {
// ...
}视图中列的可空性
对于用 Dart 定义的视图,作为 Expression getter 定义的表达式始终是可空的。此行为与 TypedResult.read 方法一致,该方法用于从带有自定义列的复杂 select 语句中读取结果。
引用其他表列的列,如果被引用的列本身是可空的,或者该表不是通过内连接(inner join)加入的(因为在这种情况下整个表都可能为 null),那么该列也是可空的。
以上面的视图为例:
itemCount列是可空的,因为它是一个复杂的Expression。description列(引用自categories.description)是不可空的。这是因为它引用了categories表,而该表是视图 select 语句的主表。