Flutter
GraphQL
使用 GraphQL 在 Flutter 应用中管理 Back4App 关系数据
20 分
使用 graphql 存储关系数据 介绍 在过去的两个教程中,我们在 flutter 应用项目中对 back4app 数据库进行了 graphql 查询和变更。我们使用 https //pub dev/packages/graphql flutter/install 作为我们的 graphql 客户端,因为这是一个非常强大且广泛使用的项目。在这些教程中,我们使用了一个非常简单的数据模型,包含我们类中最常见的类型。 back4app 是一个灵活的平台,允许您创建、存储和查询关系数据。在本教程中,我们将深入探讨这一能力,向您展示如何在 back4app 后端保存和查询关系数据时使用关系和指针。此外,我们还将探索 back4app 提供的其他数据类型,如:geopointer 和 datetime。 目标 在本文的最后,您将能够 创建/更新和删除关系数据(使用指针和关系) 创建/更新地理指针 创建/更新日期时间。 先决条件 要完成本教程,您需要: 确保您已阅读前两个指南 https //www back4app com/docs/flutter/graphql/flutter graphql project with source code download 和 https //www back4app com/docs/flutter/graphql/flutter crud app example 从 https //github com/templates back4app/flutter graphql/tree/complex mutations 下载项目文件,其中包括之前的代码以及您需要的新 gui。 在 vs code 或 android studio 等 flutter ide 中打开下载的项目。 可以在 https //www back4app com/ 创建 back4app 账户。 按照之前的教程将您的教程连接到 back4app。 https //www back4app com/docs/flutter/graphql/flutter graphql project with source code download 1 设置后端 在我们的 https //www back4app com/docs/flutter/flutter crud app example 中,我们的数据模型非常简单,只有一个类:语言。现在我们将通过添加两个新类并将它们与语言关联来使其更复杂。 创始人格式 列名 描述 名称 语言创始人的名字 列名 描述 名称 公司所有者的名字 拥有日期 公司获得所有权的日期 总部 公司的总部位置 我们将创建一个一对一的关系,连接类 language 和类 founder ,使用 parse pointers,这将告诉我们特定语言的创始人。然后,我们将创建一个一对多的关系,连接类 language 和类 ownership ,使用 parse relations,这将告诉我们哪个组织/公司拥有该语言,他们的总部以及他们获得该语言所有权的日期。数据模型将如下所示 在我们进入应用程序之前,让我们在后端创建我们所需的类和数据。前往您的 back4app 应用程序,然后进入 graphql playground。使用下面的变更,创建一个类 founder ,我们将在其中存储语言创始人的名字。 1 mutation createclass { 2 createclass(input { 3 name "founder" 4 schemafields { 5 addstrings \[{name "name"}] 6 } 7 }){ 8 class{ 9 schemafields{ 10 name 11 typename 12 } 13 } 14 } 15 } 现在让我们用一些创始人的名字来填充我们的类。在接下来的步骤中,我们将使用这些数据来创建指向创始人类的新语言。请在 back4app graphql playground 上使用下面的变更来创建您的创始人。 1 mutation createobject{ 2 createfounder(input {fields {name "james gosling"}}){ 3 founder{ 4 id 5 name 6 } 7 } 8 } 在这里,我们输入了 java 编程语言创始人的名字。您也可以为其他人做类似的操作,但现在这对于我们的指南来说已经足够了。 让我们创建一个 ownership 类,在这里我们将存储语言所有权、成立日期(日期时间)和所有者的总部位置(地理指针)。稍后我们将创建语言类与所有权之间的关系。请运行下面的代码以创建该类 1 mutation createclass { 2 createclass(input { 3 name "ownership" 4 schemafields { 5 addstrings \[{name "name"}] 6 adddates \[{name "date owned"}] 7 } 8 }){ 9 class{ 10 schemafields{ 11 name 12 typename 13 } 14 } 15 } 16 } 现在使用以下变更填充 ownership 类 1 mutation createobject{ 2 createownership(input {fields {name "sun microsystems"}}){ 3 ownership{ 4 id 5 name 6 } 7 } 8 } 1 mutation createobject{ 2 createownership(input {fields {name "oracle"}}){ 3 ownership{ 4 id 5 name 6 } 7 } 8 } 现在刷新页面,转到 ownership ownership 类在数据库浏览器中。选择右上角的 添加新列 。从第一个下拉菜单中选择 geopoint,并在第二个文本字段中命名为 headquarters 。然后保持所有内容不变,按下 添加列 按钮。 然后去你的 语言 语言 类在数据库浏览器上。让我们添加对 所有权 所有权 和 创始人 创始人 类的关系。点击 添加新列 ,然后选择数据类型指针和目标类: 创始人 创始人 。给列起同样的名字 创始人 然后按添加列 现在通过添加一个名为所有权的新列,使用数据类型关系并选择类 所有权 所有权 来重复这个过程 现在你已经准备好在你的flutter应用程序中使用数据模型,并开始保存和更新数据 2 创建/添加和删除指针 现在您需要从我们的 https //github com/templates back4app/flutter graphql/tree/complex mutations 下载项目模板代码并在您的 ide 中打开。要将您的项目连接到 back4app,请转到 graphql playground,然后复制下面图像中显示的密钥和 api url。现在将它们粘贴到 constants dart constants dart 中并运行您的项目。 在您的模拟器中运行应用程序。转到 m 浮动按钮的底部。这将带我们到我们执行简单变更的页面。在这里,您会找到一个额外的浮动操作按钮 cm 这是我们将用于执行复杂 graphql 变更的按钮。点击 cm 按钮,您将看到另外四个按钮,每个按钮对应于我们在本指南中将要进行的操作。 现在打开 databaseutils dart databaseutils dart 文件并向下滚动到 addpointers() addpointers() 方法。在这里我们将添加添加指针的逻辑。我们将把 james gosling 指定为 java 语言的创始人。因此,您首先需要前往您的 back4app 后端并复制创始人(james gosling)和语言(java) objectid objectid 更新/创建指向数据的指针 继续在我们的应用程序中 databaseutils dart databaseutils dart 和在 addpointers() addpointers() 方法中初始化一个 string addpointerquery string addpointerquery ,我们将在其中分配用于添加指针的 graphql 查询,如下所示 1 string addpointerquery= 2 ''' 3 mutation addpointer(\\$languageid id!, \\$founderid updatelanguagefieldsinput! ){ 4 updatelanguage(input {id \\$languageid, fields \\$founderid}) 5 { 6 language{ 7 objectid 8 } 9 } 10 } 11 '''; 并初始化 final variable final variable 来分配变量,注意我们正在将 rowobjectid rowobjectid 和 pointersid pointersid 作为参数,其中 rowobjectid rowobjectid 我们将指向的行的对象 id pointersid pointersid 要指向的行的对象 id。 所以声明 variable variable 如下 1 final variable={ 2 "userid" rowobjectid, 3 "founderid" { 4 "founder" { 5 "link" pointersid 6 } 7 } 8 }; 现在像上一个指南一样,我们将初始化 graphqlclient graphqlclient 并借助 queryoptions() queryoptions() 发送查询,并通过 queryresults() queryresults() 返回其实例。 1 graphqlconfiguration configuration = graphqlconfiguration(); 2 graphqlclient client = configuration clienttoquery(); 3 4 queryresult queryresult = await client query( 5 queryoptions(documentnode gql(addpointerquery), variables variable), 6 ); 7 return queryresult; 这就是你的 addpointers() addpointers() 方法应该是的样子: 1 future\<queryresult> addpointers(string rowobjectid, string pointersid) async{ 2 print('addpointers'); 3 //code for add/update pointers 4 string addpointerquery= 5 ''' 6 mutation addpointer(\\$languageid id!, \\$founderid updatelanguagefieldsinput! ){ 7 updatelanguage(input {id \\$languageid, fields \\$founderid}) 8 { 9 language{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "userid" rowobjectid, 17 "founderid" { 18 "founder" { 19 "link" pointersid 20 } 21 } 22 }; 23 graphqlconfiguration configuration = graphqlconfiguration(); 24 graphqlclient client = configuration clienttoquery(); 25 26 queryresult queryresult = await client query( 27 queryoptions(documentnode gql(addpointerquery), variables variable), 28 ); 29 return queryresult; 30 } 现在热重启你的应用,去到 cm 按钮在变更页面,然后按下设置 添加指针 按钮。在这里输入行 objectid objectid ,在第一个文本框中添加指针,并在第二个文本框中输入它将指向的行 objectid objectid ,然后按 完成 。现在检查你的仪表板,你应该能在 创始人 列下看到一个关系。你可以点击它,它会带你到指向 创始人 类的行。 删除指向数据的指针 现在继续到方法 deletepointers() deletepointers() ,我们将在这里编写删除关系的逻辑。要删除关系,您只需对上面的查询进行小的更改,也就是说,在变量中只需将 "link" "link" 更改为 "remove" "remove" 所以在初始化 final variable final variable 后,它将是 1 final variable={ 2 "languageid" rowobjectid, 3 "founderid" { 4 "founder" { 5 "remove" pointersid 6 } 7 } 8 }; 其他一切看起来与 addpointers() addpointers() 完全相同。所以你的 deletepointers() deletepointers() 方法看起来是 1 future\<queryresult> deletepointers(string rowobjectid, string pointersid) async{ 2 print('deletepointers'); 3 //code for delete pointers 4 string removepointersquery= 5 ''' 6 mutation addpointer(\\$languageid id!, \\$founderid updatelanguagefieldsinput! ){ 7 updatelanguage(input {id \\$languageid, fields \\$founderid}) 8 { 9 language{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "languageid" rowobjectid, 17 "founderid" { 18 "founder" { 19 "remove" pointersid 20 } 21 } 22 }; 23 graphqlconfiguration configuration = graphqlconfiguration(); 24 graphqlclient client = configuration clienttoquery(); 25 26 queryresult queryresult = await client query( 27 queryoptions(documentnode gql(removepointersquery), variables variable), 28 ); 29 return queryresult; 30 31 } 您现在可以前往您的 back4app 仪表板,看到特定行的 创始人 列已被删除。 3 创建/添加和删除日期时间数据 如果您还记得,我们在 ownership 中创建了一个类, step 1 并存储了一些数据。这些是拥有 java 编程语言的公司的名称。所以首先让我们输入他们获得所有权的日期。 让我们继续到 databaseutils dart databaseutils dart 并创建或向下滚动到 adddatetime() adddatetime() 函数。在这里我们将编写逻辑,将日期时间数据类型添加到我们的类中。初始化 string adddatetimequery string adddatetimequery 并将其赋值为创建日期时间数据的查询: 1 string adddatetimequery= 2 ''' 3 mutation addtime(\\$rowid id!,\\$dateowned date!){ 4 updateownership(input {id \\$rowid, fields {date owned \\$dateowned}}) 5 { 6 ownership{ 7 objectid 8 } 9 } 10 } 11 '''; 并将 最终变量 最终变量 赋值为: 1 final variable={ 2 "rowid" rowobjectid, 3 "dateowned" datetime 4 }; 现在初始化 graphqlclient graphqlclient 并通过 queryoption() queryoption() 传递查询。这是你的函数的样子 1 future\<queryresult> adddatetime(string rowobjectid, string datetime) async{ 2 print('adddatetime'); 3 //code for add/update date time 4 string adddatetimequery= 5 ''' 6 mutation addtime(\\$rowid id!,\\$dateowned date!){ 7 updateownership(input {id \\$rowid, fields {date owned \\$dateowned}}) 8 { 9 ownership{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "rowid" rowobjectid, 17 "dateowned" datetime 18 }; 19 graphqlconfiguration configuration = graphqlconfiguration(); 20 graphqlclient client = configuration clienttoquery(); 21 queryresult queryresult = await client query( 22 queryoptions(documentnode gql(adddatetimequery), variables variable), 23 ); 24 return queryresult; 25 } 现在 热重启 应用程序,并记下包含 sun microsystems 的行的 objectid 在 name 列中。按下 添加日期时间 按钮。现在在第一个文本字段中输入记下的 objectid 并输入 “02 24 1982” 作为 mm dd yyyy 格式,按下 完成 按钮。 前往你的 back4app 后端,你会看到日期以 1982年2月24日 00 00 00 utc 的形式,这意味着它已将数据类型识别为日期时间数据类型。同样,你可以为 oracle 添加 “01 27 2010” 的 date owned 4 添加/更新 geopointer 数据 让我们添加 geopointer 数据以定位公司总部来自于 ownership 表。 继续到 database utils dart database utils dart 文件并向下滚动到 addgeopointers() addgeopointers() 函数。现在初始化 string addgeopointers string addgeopointers 并分配相应的查询 1 string addgeopointers= 2 ''' 3 mutation addgeopointer(\\$objectid id!,\\$latitude float!,\\$longitude float!){ 4 updateownership(input {id \\$objectid, fields { headquarters {latitude \\$latitude, longitude \\$longitude}}}) 5 { 6 ownership{ 7 objectid 8 } 9 } 10 } 11 '''; 和 最终变量 最终变量 如下 1 final variable={ 2 "objectid" rowobjectid, 3 "latitude" double parse(latitude), 4 "longitude" double parse(longitude), 5 }; 由于 纬度 纬度 和 经度 经度 是双精度值,我们需要将它们从字符串解析为双精度值,然后再发送。初始化 grapqlclient grapqlclient 并通过 queryoption() queryoption() 传递查询。这就是你的 addgeopointers() addgeopointers() 函数的样子 1 future\<queryresult> addgeopointers(string rowobjectid, string latitude, string longitude) async{ 2 print('add geopointers'); 3 //code for add/update geopointers 4 string addgeopointers= 5 ''' 6 mutation addgeopointer(\\$objectid id!,\\$latitude float!,\\$longitude float!){ 7 updateownership(input {id \\$objectid, fields { headquarters {latitude \\$latitude, longitude \\$longitude}}}) 8 { 9 ownership{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable={ 16 "objectid" rowobjectid, 17 "latitude" double parse(latitude), 18 "longitude" double parse(longitude), 19 }; 20 graphqlconfiguration configuration = graphqlconfiguration(); 21 graphqlclient client = configuration clienttoquery(); 22 queryresult queryresult = await client query( 23 queryoptions(documentnode gql(addgeopointers), variables variable), 24 ); 25 return queryresult; 26 } 热重启您的应用程序并选择 添加地理指针 按钮。输入 37 35 37 35 在第一个文本框中,输入 121 95 121 95 在第二个文本框中。输入 objectid 的行,名称为 sun microsystems ,然后按完成。现在继续到您的 back4app 后端,您将看到 (37 35, 121 95) 这是总部的坐标,并表明它被识别为地理指针。 5 添加/更新和删除关系 在指针中,我们只能指向一行,但借助关系,我们可以连接多行。所以让我们将我们的 语言 表与这两行的 所有权 进行关系,针对 java 语言 添加/更新关系 继续到 database utils dart database utils dart 文件并继续到 addrelation() addrelation() 函数以编写逻辑。初始化 string addrelationquery string addrelationquery 并将关系查询分配如下 1 string addrelationquery= 2 ''' 3 mutation addrelation(\\$objectid id!, \\$relationid ownershiprelationinput){ 4 updatelanguage(input {id \\$objectid, fields {ownership \\$relationid}}) 5 { 6 language{ 7 objectid 8 } 9 } 10 } 11 '''; 和 最终变量 最终变量 将是 1 final variable= { 2 "objectid" objectid, 3 "relationid" relationid 4 }; 所以在初始化 graphqlclient graphqlclient 并像之前一样传递查询,这就是你的 database utils dart database utils dart 的样子 1 future\<queryresult> addrelation(string rowobjectid, string relationid) async{ 2 //code for add/update relation 3 print('addrelation'); 4 string addrelationquery= 5 ''' 6 mutation addrelation(\\$objectid id!, \\$relationid ownershiprelationinput){ 7 updatelanguage(input {id \\$objectid, fields {ownership \\$relationid}}) 8 { 9 language{ 10 objectid 11 } 12 } 13 } 14 '''; 15 final variable= { 16 "objectid" rowobjectid, 17 "relationid" { 18 "add" relationid 19 } 20 }; 21 graphqlconfiguration configuration = graphqlconfiguration(); 22 graphqlclient client = configuration clienttoquery(); 23 queryresult queryresult = await client query( 24 queryoptions(documentnode gql(addrelationquery), variables variable), 25 ); 26 print(queryresult); 27 return queryresult; 28 } 成功 您的应用程序终于在 back4app 上存储了关系、日期时间和地理指针数据! 结论 在本指南中,我们学习了如何使用 graphql 在 back4app 上存储关系数据,来自 flutter 应用项目。我们还处理了其他 graphql 变更,如地理指针和日期时间,创建、更新和删除数据。在下一个教程中,我们将深入探讨对我们的 flutter 应用的查询。 本指南由 asim junain 编写,来自 https //www back4app com/partners/software development company