继续创作,加速成长!这是我参与「日新方案 10 月更文应战」的第17天,点击检查活动详情


Isar:用于 Futter 可跨平台的超快数据库

官方文档:Home | Isar Database

pub:isar | Dart Package (flutter-io.cn)

本文翻译自:Links | Isar Database

译时版本:3.0.2


链接

链接能够体现方针之间的联系,如 谈论的作者(用户)。
运用 Isar 的链接能够体现 1对1,1对多,多对多。
比较 嵌入方针,运用 链接 有些不符合惯例思维,假如可能的话,应该运用嵌入方针。

能够认为链接是包括相相关系的一个独自的表。
它类似于 SQL 的连接,但是有不同的特性集和 API 。

IsarLink

IsarLink<T>能够包括 0 个或一个相关的方针,所以它能够用来体现 对1 的联系。
IsarLink 有一个叫作 value 的特点,它保有链接的方针。

链接是推迟加载的,所以需求清晰告知IsarLink加载或保存这个value
可调用linkProperty.load()linkProperty.save() 来完成。

链接来历调集和链接方针调集的 id 特点应该是 不是 final 的。

从非 Web 的方针,链接会在第一次运用它们时主动加载。
让咱们开端向调集中增加一个 IsarLink:

@Collection()
class Teacher {
  int? id;
  late String subject;
}
@Collection()
class Student {
  int? id;
  late String name;
  final teachers = IsarLink<Teacher>();
}

咱们界说了一个相关 teacher (教师)和 student (学生) 的链接。
该示例中每个学生清晰只有一个教师。

首先咱们创立一个 teacher 然后指定给一个学生。
正如在示例中看到的,咱们需求手动(显式地)put()(增加)某个学生。

final mathTeacher = Teacher()..subject = 'Math';
final linda = Student()
  ..name = 'Linda'
  ..teachers.value = mathTeacher;
await isar.writeTxn((isar) async {
  await isar.students.put(linda);
});

现在咱们能够运用该链接:

final linda = await isar.students.where().nameEqualTo('Linda').findFirst();
final teacher = linda.teacher.value; // > Teacher(subject: 'Math')

现在试着用同步代码来做相同的处理。
咱们不需求手动保存链接因为 .putSync()会主动保存一切链接。
它甚至会为咱们创立 teacher (教师)。

final englishTeacher = Teacher()..subject = 'English';
final david = Student()
  ..name = 'David'
  ..teacher.value = englishTeacher;
isar.writeTxnSync(() {
  isar.students.putSync(david);
});

IsarLinks

上面示例中,一个学生能够有多个教师会更合理。
幸运的是 Isar 有 IsarLinks<T> ,它能包括多个相关的方针,体现为 对多 的联系。

IsarLinks<T>承继了Set<T>,所以它暴露了一切可用于 set 的办法。

IsarLinks的行为更像IsarLink,也是推迟加载的。
要加载一切相关的方针,可调用linkProperty.load()
要将一切的改动永久化,可调用 linkProperty.save()

在内部 IsarLinkIsarLinks 以相同的方式体现。
这使咱们能够从之前的 IsarLink<Teacher> 升级到 IsarLinks<Teacher> 为单个学生指定多个教师(不会丢失数据)。

@Collection()
class Student {
  int? id;
  late String name;
  final teachers = IsarLinks<Teacher>();
}

这能正常工作是因为咱们没有改动链接的名称(teacher),所以 Isar 一开端就会记住该链接。

final biologyTeacher = Teacher()..subject = 'Biology';
final linda = isar.students.where()
  .filter()
  .nameEqualTo('Linda')
  .findFirst();
print(linda.teachers); // {Teacher('Math')}
linda.teachers.add(biologyTeacher);
await isar.writeTxn(() async {
  await linda.teachers.save();
});
print(linda.teachers); // {Teacher('Math'), Teacher('Biology')}

Backlink(反向链接)

我听到你问 “假如想要体现反向的联系该用什么?”。
不用忧虑,咱们现在会介绍反向链接 。

反向链接是反方向的链接。
每个链接都有一个隐式的反向链接 。
要在应用中使其可用,能够用 @Backlink()IsarLinkIsarLinks 增加注解。

反向链接无需额定的内存或资源,能够自在增加、移除和重命名而不会丢失数据。

咱们想知道某个教师有哪些学生,能够界说一个反向链接:

@Collection()
class Teacher {
  int? id;
  late String subject;
  @Backlink(to: 'teachers')
  final students = IsarLinks<Student>();
}

咱们需求为链接指定指向它的反向链接。
在两个方针之间也能够有多个不同的链接。

初始化链接

IsarLinkIsarLinks都有一个无参的构造办法,应该用来在方针被创立时分配链接特点。
将链接特点设置为 final 是好的实践。

初次 put()方针时,链接会初始化源调集和方针调集,然后能够调用办法、如 load()save() 。链接会在创立后马上开端跟踪变化,这样就能够增加或移除相关了 甚至在链接初始化之前。

移动链接到另一个方针是违背规则的。