Flutter 中 Parse SDK 实现多对多关系的详细指南
Flutter中的多对多关系
介绍
在之前的指南中,我们学习了如何使用一对多关系,我们将继续我们的项目。在本指南中,我们将重点关注最常见的关系:多对多关系。在Parse中有三种方法可以创建多对多关系。
- 第一种是使用Parse 关系, 这是创建和查询时间最快的方法。我们将在本指南中使用此方法。
- 第二种是使用数组的 指针,这可能会导致查询时间变慢,具体取决于它们的大小。
- 第三种是使用连接表,这是经典数据库中的一个概念。当存在多对多关系时,我们将每个 objectId或 指针从两边组合在一起,以构建一个新的单独表格,在其中跟踪关系。
在本指南中,您将实现一个 多对多 关系,在一个Flutter图书注册应用程序中使用Parse 关系. 您将学习如何创建和查询多对多数据关系,以及如何执行查询以返回来自相关对象的数据,使用Back4App和Flutter SDK。
前提条件
- 注意:在之前的指南中创建的 Flutter 应用
- 完成之前的指南,以便更好地理解 一对多关系 类
- 一台运行 Android 或 iOS 的设备(或虚拟设备)。
1 - 运行图书应用模板
如果您尚未完成之前的指南,您可以从我们的代码库中克隆并运行完整的 图书 Flutter 应用 项目。您还可以查看 之前的指南 以更好地理解应用模板。下面您可以找到图书注册数据模型的可视化表示。

2 - 保存一本书对象及其作者
打开之前指南中的 Flutter 项目 Flutter 中的一对多关系。搜索文件中的函数 doSaveBook ,并在 main.dart 文件中用下面的代码替换它。这个函数将在 Back4app 数据存储中创建一个新的书籍对象,并建立关系。
1 final book = ParseObject('Book')
2 ..set('title', controllerTitle.text.trim())
3 ..set('year', int.parse(controllerYear.text.trim()))
4 //the objectId will be converted to a Pointer on the save() method
5 ..set('genre', ParseObject('Genre')..objectId = genre.objectId)
6 //you can also convert to a Pointer object before the saving using the .toPointer() method
7 ..set('publisher',
8 (ParseObject('Publisher')..objectId = publisher.objectId).toPointer())
9 //Saving a List of Authors for the Book
10 ..addRelation(
11 'authors',
12 authors
13 .map((o) => ParseObject('Author')..objectId = o.objectId)
14 .toList());
15
16 await book.save();要构建此函数,请按照以下步骤操作:
- 1. 创建一个新的 Parse 实例书籍 类,使用命令 ParseObject('书籍').
- 2. 使用 设置 函数来设置此对象的字段。
- 2.1.标题是一个文本属性,从文本控制器接收值。
- 2.2.类型 通过定义一个 ParseObject 与 objectId 的选定 类型. (Parse将在保存时转换为指针)
- 2.3.发布者 通过定义一个 ParseObject 来接收值,objectId 的选定 发布者. (请注意,我们可以为 Parse 指定我们想要保存为一个 指针 使用 toPointer() 方法)
- 2.4.作者. 我们称之为 addRelation 方法的 ParseObject, 发送一个 ParseObject 的列表,带有 objectId 的选定 作者.
- 3. 调用保存 函数在 ParseObject, 这将有效地将对象注册到您的数据库中,在 Back4app 控制面板中.
运行应用程序并测试新的 doSaveBook() 函数
- 首先,访问仪表板并删除在之前指南中注册的书籍。
- 点击 添加书籍 按钮。
- 填写书籍信息和作者。
- 点击 保存书籍 按钮

要确认新对象是否与关系一起保存在数据库中,您可以访问 Back4app Dashboard 并访问 Book 类。

在您的仪表板中点击对象指针/关系值将带您到引用的对象条目。这看起来可能是一个无害的功能,但这使得调试和错误追踪比手动搜索快得多。
3 - 查询带有关系的书籍详情
此功能将在 Back4app 数据库中查询书籍详情,返回关系数据。在某些情况下,您可能希望在一个查询中返回多种类型的相关对象。您可以使用 includeObject 方法来实现。在我们的示例中,我们希望返回书籍,并包含来自类型和出版商的信息。
在文件中搜索函数 getBookDetail ,然后在 main.dart 文件中替换以下代码 getBookDetail(ParseObject book) 函数:
1 QueryBuilder<ParseObject> queryBook =
2 QueryBuilder<ParseObject>(ParseObject('Book'))
3 ..whereEqualTo('objectId', book.objectId)
4 ..includeObject(['publisher', 'genre']);
5
6 final ParseResponse responseBook = await queryBook.query();
7
8 if (responseBook.success && responseBook.results != null) {
9 final book = (responseBook.results.first) as ParseObject;
10 bookTitle = book.get<String>('title');
11 bookYear = book.get<int>('year');
12 bookGenre = book.get<ParseObject>('genre').get<String>('name');
13 bookPublisher = book.get<ParseObject>('publisher').get<String>('name');
14 loadedData = true;
15 }
16
17 QueryBuilder<ParseObject> queryAuthors =
18 QueryBuilder<ParseObject>(ParseObject('Author'))
19 ..whereRelatedTo('authors', 'Book', book.objectId);
20
21 final ParseResponse responseAuthors = await queryAuthors.query();
22
23 if (responseAuthors.success && responseAuthors.results != null) {
24 bookAuthors = responseAuthors.results
25 .map((e) => (e as ParseObject).get<String>('name'))
26 .toList();
27 }要构建此函数,请按照以下步骤操作:
- 创建一个ParseQuery对象的实例,用于 Book 类。插入一个条件到查询中,以搜索 Books,其中 objectId 字段等于所选书籍的 objectId。
- 我们使用 includeObject 方法,告知我们希望在同一查询中返回的指针字段:类型和出版商。您还可以使用点表示法进行多级 includeObject。示例:`..includeObject([‘post’, ‘post.authors’]);
- 使用 query() 方法进行查询的搜索。
- 如果操作成功,将返回 Book 中的对象。
- 我们使用 get 方法来检索数据。对于指针字段,我们首先需要检索指针,然后获取其数据。示例:bookGenre = book.get<ParseObject>('genre').get<String>('name');
在处理的第二阶段,我们需要恢复与书籍相关的作者。
要构建此功能,请按照以下步骤操作:
- 为 ParseQuery 类创建一个 Authors 对象。在查询中插入一个条件,使用 whereRelatedTo 操作符来搜索 Authors 与 Book, 其中 Book 等于所选书籍的 objectId。
- 使用 query() 方法进行查询的搜索。
- 如果操作成功,将返回 Book 中的对象。
- 我们使用 get 方法来检索数据。
运行应用程序并测试新的查询。
首先,点击 列表出版商/书籍 按钮。

从列表中选择一本书。下一个屏幕将显示书籍及其关系的数据。

完成!
此时,您已学习如何创建和查询多对多关系,以及如何在 Flutter 中执行返回相关对象数据的查询。