Flutter
...
Data Queries
Flutter 关系数据查询教程:使用Parse进行复杂查询
10 分
在flutter中解析关系查询 介绍 您已经看到 如何存储关系数据对象 使用parse pointer和parse relations数据类型。您已经了解到在parse中,可以将任何parseobject作为其他parseobject中的值,从而建立它们之间的关系。在内部,parse框架将把被引用的对象存储在一个地方以保持一致性。这可以在构建和运行复杂查询时为您提供额外的能力。 此外,您已经 学习了如何使用querybuilder ,使用get可以从back4app中检索单个parseobject。还有许多其他方法可以使用querybuilder检索数据。 在本指南中,您将深入研究querybuilder类,并查看可以用来构建关系查询的方法。您将使用一个简单的数据库类和一些模拟数据来使用flutter在back4app上执行查询。 先决条件 要完成本教程,您需要: android studio https //developer android com/studio 或 安装 vs code (带有 插件 dart 和 flutter) 一个在 back4app 上 创建的应用 : 注意: 请遵循 新 parse 应用教程 以了解如何在 back4app 上创建 parse 应用。 一个连接到 back4app 的 flutter 应用。 注意: 请遵循 在 flutter 项目中安装 parse sdk 以创建一个连接到 back4app 的 flutter 项目。 一台运行 android 或 ios 的设备(或虚拟设备)。 目标 从 flutter 应用查询存储在 back4app 上的关系数据。 1 理解 querybuilder 类 任何 parse 查询操作都使用 querybuilder 对象类型,它将帮助您在应用程序中从数据库中检索特定数据。 要创建一个新的 querybuilder,您需要将所需的 parseobject 子类作为参数传递,该子类将包含您的查询结果。 了解 querybuilder 仅在调用检索方法查询后才会解析是至关重要的,因此可以设置查询并在实际调用之前链接多个修饰符。 1 // this will create your query 2 querybuilder\<parseobject> querybook = 3 querybuilder\<parseobject>(parseobject('book')); 4 5 // the query will resolve only after calling this method 6 final parseresponse apiresponse = await querybook query(); 7	 8 if (apiresponse success && apiresponse results != null) { 9 10 } else { 11 12 } 你可以在官方文档中阅读更多关于 querybuilder 类的内容 这里 在 back4app 上使用 javascript 控制台 在你的 back4app 应用程序的仪表板中,你会找到一个非常有用的 api 控制台,在其中你可以直接运行 javascript 代码。在本指南中,你将使用它在 back4app 中存储数据对象。在你的应用主仪表板中,转到 core >api 控制台 >javascript。 2 在 back4app 上保存数据 要运行本指南中的查询,您首先需要为您的应用填充一些数据。 类包括: 作者 , 书籍 , 出版商 和 书店 其中 书籍 与 出版商 有 1\ n 关系,与 作者 有 n\ n 关系,而 书店 与书籍有 n\ n 关系。 这里是 parse object 类的创建代码,所以请在您的 api 控制台中运行它 1 // add objects and create tables 2 // authors 3 const authora = new parse object('author'); 4 authora set('name', 'aaron writer'); 5 await authora save(); 6 7 const authorb = new parse object('author'); 8 authorb set('name', 'beatrice novelist'); 9 await authorb save(); 10 11 const authorc = new parse object('author'); 12 authorc set('name', 'casey columnist'); 13 await authorc save(); 14 15 const authord = new parse object('author'); 16 authord set('name', 'gary stur'); 17 await authord save(); 18 19 const authore = new parse object('author'); 20 authore set('name', 'mary sue'); 21 await authore save(); 22 23 // publishers 24 const publishera = new parse object('publisher'); 25 publishera set('name', 'acacia publishings'); 26 await publishera save(); 27 28 const publisherb = new parse object('publisher'); 29 publisherb set('name', 'birch distributions'); 30 await publisherb save(); 31 32 const publisherc = new parse object('publisher'); 33 publisherc set('name', 'acacia distributions'); 34 await publisherc save(); 35 36 37 // books 38 const booka = new parse object('book'); 39 booka set('title', 'a love story'); 40 booka set('publisher', publishera); 41 booka set('publishingdate', new date('05/07/1998')); 42 const bookarelation = booka relation("authors"); 43 bookarelation add(authora); 44 await booka save(); 45 46 const bookb = new parse object('book'); 47 bookb set('title', 'benevolent elves'); 48 bookb set('publisher', publisherb); 49 bookb set('publishingdate', new date('11/31/2008')); 50 const bookbrelation = bookb relation("authors"); 51 bookbrelation add(authorb); 52 await bookb save(); 53 54 const bookc = new parse object('book'); 55 bookc set('title', 'can you believe it?'); 56 bookc set('publisher', publisherb); 57 bookc set('publishingdate', new date('08/21/2018')); 58 const bookcrelation = bookc relation("authors"); 59 bookcrelation add(authora); 60 bookcrelation add(authorc); 61 await bookc save(); 62 63 // bookstore 64 const bookstorea = new parse object('bookstore'); 65 bookstorea set('name', 'books of love'); 66 const bookstorearelation = bookstorea relation("books"); 67 bookstorearelation add(booka); 68 await bookstorea save(); 69 70 const bookstoreb = new parse object('bookstore'); 71 bookstoreb set('name', 'fantasy books'); 72 const bookstorebrelation = bookstoreb relation("books"); 73 bookstorebrelation add(bookb); 74 await bookstoreb save(); 75 76 const bookstorec = new parse object('bookstore'); 77 bookstorec set('name', 'general books'); 78 const bookstorecrelation = bookstorec relation("books"); 79 bookstorecrelation add(booka); 80 bookstorecrelation add(bookc); 81 await bookstorec save(); 82 83 console log('success'); 运行此代码后,您现在应该在数据库中拥有 author、publisher、book 和 bookstore 类。 您的新类应该看起来像这样 现在让我们看看每个 querybuilder 方法的示例,以及它们的简要说明。 3 查询数据 现在您已经有了一个填充的类,我们可以执行一些关系查询。 现在您已经填充了所有类,我们可以在其中执行一些关系查询。 让我们开始通过出版商过滤书籍结果,搜索属于出版商 “acacia publishings” (或“出版商a”)的书籍,使用基本的 whereequalto 方法进行关系指针查询 1 // get publishera object 2 final querybuilder\<parseobject> publisherquerya = 3 querybuilder\<parseobject>(parseobject('publisher')) 4 whereequalto('name', 'acacia publishings'); 5 6 final parseresponse publisherresponse = await publisherquerya query(); 7 if (!publisherresponse success) { 8 return; 9 } 10 final publishera = publisherresponse results? first as parseobject; 11 12 // query books with publishera 13 final querybuilder\<parseobject> bookquery = 14 querybuilder\<parseobject>(parseobject('book')) 15 whereequalto('publisher', publishera); 16 17 final parseresponse bookresponse = await bookquery query(); 18 if (!bookresponse success) { 19 return; 20 } 21 22 for (var book in bookresponse results as list\<parseobject>) { 23 print(book get('title')); 24 } 现在让我们查询哪些书店对象包含出版日期晚于 2010 年 1 月 1 日的书籍,使用内部查询与 wheregreaterthan 方法,然后使用 wherematchesquery 方法 1 // create inner book query 2 final querybuilder\<parseobject> bookquery = 3 querybuilder\<parseobject>(parseobject('book')) 4 wheregreaterthan('publishingdate', datetime(2010, 01, 01)); 5 6 // query bookstore using inner book query 7 final querybuilder\<parseobject> bookstorequery = 8 querybuilder\<parseobject>(parseobject('bookstore')) 9 wherematchesquery('books', bookquery); 10 11 final parseresponse bookstoreresponse = await bookstorequery query(); 12 if (!bookstoreresponse success) { 13 return; 14 } 15 16 for (var b in bookstoreresponse results as list\<parseobject>) { 17 print(b get('name')); 18 } 现在让我们创建另一个查询,寻找与书籍 can you believe it 相关的作者,使用 whererelatedto 1 // get book object 2 final querybuilder\<parseobject> bookquery = 3 querybuilder\<parseobject>(parseobject('book')) 4 whereequalto('title', 'can you believe it?'); 5 6 final parseresponse bookresponse = await bookquery query(); 7 if (!bookresponse success) { 8 return; 9 } 10 11 final book = bookresponse results? first as parseobject; 12 13 // get author with relation with book can you believe it? 14 final querybuilder\<parseobject> authorsquery = 15 querybuilder\<parseobject>(parseobject('author')) 16 whererelatedto('authors', 'book', book objectid!); 17 18 final parseresponse authorresponse = await authorsquery query(); 19 20 // let's show the results 21 if (authorresponse success && authorresponse results != null) { 22 for (var a in authorresponse results! as list\<parseobject>) { 23 print(a get('name')); 24 } 25 } 4 从 flutter 查询 现在让我们在 flutter 应用中使用我们的示例查询,界面简单,包含一个显示结果的列表和三个用于调用查询的按钮。 打开你的 flutter 项目,进入 main dart 文件,清理所有代码,并用以下内容替换它: 1 import 'package\ flutter/cupertino dart'; 2 import 'package\ flutter/material dart'; 3 import 'package\ parse server sdk flutter/parse server sdk dart'; 4 5 void main() async { 6 widgetsflutterbinding ensureinitialized(); 7 8 final keyapplicationid = 'your app id here'; 9 final keyclientkey = 'your client key here'; 10 final keyparseserverurl = 'https //parseapi back4app com'; 11 12 await parse() initialize(keyapplicationid, keyparseserverurl, 13 clientkey keyclientkey, debug true); 14 15 runapp(materialapp( 16 title 'flutter geopoint', 17 debugshowcheckedmodebanner false, 18 home homepage(), 19 )); 20 } 21 22 class homepage extends statefulwidget { 23 @override 24 homepagestate createstate() => homepagestate(); 25 } 26 27 class homepagestate extends state\<homepage> { 28 list\<parseobject> results = \<parseobject>\[]; 29 double selecteddistance = 3000; 30 31 void doquerypointer() async { 32 // get publishera object 33 final querybuilder\<parseobject> publisherquerya = 34 querybuilder\<parseobject>(parseobject('publisher')) 35 whereequalto('name', 'acacia publishings'); 36 37 final parseresponse publisherresponse = await publisherquerya query(); 38 if (!publisherresponse success) { 39 return; 40 } 41 final publishera = publisherresponse results? first as parseobject; 42 43 // query books with publishera 44 final querybuilder\<parseobject> bookquery = 45 querybuilder\<parseobject>(parseobject('book')) 46 whereequalto('publisher', publishera); 47 48 final parseresponse bookresponse = await bookquery query(); 49 50 if (!bookresponse success) { 51 setstate(() { 52 results clear(); 53 }); 54 } else { 55 setstate(() { 56 results = bookresponse results as list\<parseobject>; 57 }); 58 } 59 } 60 61 void doquerymatches() async { 62 // create inner book query 63 final querybuilder\<parseobject> bookquery = 64 querybuilder\<parseobject>(parseobject('book')) 65 wheregreaterthan('publishingdate', datetime(2010, 01, 01)); 66 67 // query bookstore using inner book query 68 final querybuilder\<parseobject> bookstorequery = 69 querybuilder\<parseobject>(parseobject('bookstore')) 70 wherematchesquery('books', bookquery); 71 72 final parseresponse bookstoreresponse = await bookstorequery query(); 73 if (!bookstoreresponse success) { 74 setstate(() { 75 results clear(); 76 }); 77 } else { 78 setstate(() { 79 results = bookstoreresponse results as list\<parseobject>; 80 }); 81 } 82 } 83 84 void doqueryrelatedto() async { 85 // get book object 86 final querybuilder\<parseobject> bookquery = 87 querybuilder\<parseobject>(parseobject('book')) 88 whereequalto('title', 'can you believe it?'); 89 90 final parseresponse bookresponse = await bookquery query(); 91 if (!bookresponse success) { 92 return; 93 } 94 95 final book = bookresponse results? first as parseobject; 96 97 // get author with relation with book can you believe it? 98 final querybuilder\<parseobject> authorsquery = 99 querybuilder\<parseobject>(parseobject('author')) 100 whererelatedto('authors', 'book', book objectid!); 101 102 final parseresponse authorresponse = await authorsquery query(); 103 104 if (!authorresponse success) { 105 setstate(() { 106 results clear(); 107 }); 108 } else { 109 setstate(() { 110 results = authorresponse results as list\<parseobject>; 111 }); 112 } 113 } 114 115 void doclearresults() async { 116 setstate(() { 117 results clear(); 118 }); 119 } 120 121 @override 122 widget build(buildcontext context) { 123 return scaffold( 124 body padding( 125 padding const edgeinsets all(16 0), 126 child column( 127 crossaxisalignment crossaxisalignment stretch, 128 children \[ 129 container( 130 height 200, 131 child image network( 132 'https //blog back4app com/wp content/uploads/2017/11/logo b4a 1 768x175 1 png'), 133 ), 134 center( 135 child const text('flutter on back4app geopoint', 136 style textstyle(fontsize 18, fontweight fontweight bold)), 137 ), 138 sizedbox( 139 height 8, 140 ), 141 container( 142 height 50, 143 child elevatedbutton( 144 onpressed doquerypointer, 145 child text('query a'), 146 style elevatedbutton stylefrom(primary colors blue)), 147 ), 148 sizedbox( 149 height 8, 150 ), 151 container( 152 height 50, 153 child elevatedbutton( 154 onpressed doquerymatches, 155 child text('query b'), 156 style elevatedbutton stylefrom(primary colors blue)), 157 ), 158 sizedbox( 159 height 8, 160 ), 161 container( 162 height 50, 163 child elevatedbutton( 164 onpressed doqueryrelatedto, 165 child text('query c'), 166 style elevatedbutton stylefrom(primary colors blue)), 167 ), 168 sizedbox( 169 height 8, 170 ), 171 container( 172 height 50, 173 child elevatedbutton( 174 onpressed doclearresults, 175 child text('clear results'), 176 style elevatedbutton stylefrom(primary colors blue)), 177 ), 178 sizedbox( 179 height 8, 180 ), 181 text( 182 'result list ${results length}', 183 ), 184 expanded( 185 child listview\ builder( 186 itemcount results length, 187 itembuilder (context, index) { 188 final o = results\[index]; 189 return container( 190 padding const edgeinsets all(4), 191 decoration 192 boxdecoration(border border all(color colors black)), 193 child text('${o tostring()}'), 194 ); 195 }), 196 ) 197 ], 198 ), 199 )); 200 } 201 } 在您的应用程序仪表板中找到您的应用程序 id 和客户端密钥凭据,网址为 back4app 网站 https //www back4app com/ 在main dart中更新您的代码,使用您项目的applicationid和clientkey在back4app中 keyapplicationid = 应用程序 id keyclientkey = 客户端密钥 运行项目,应用程序将如图所示加载。 结论 在本指南的最后,您了解了关系查询在 parse 上是如何工作的,以及如何在 flutter 应用程序中在 back4app 上执行它们。在下一个指南中,您将学习如何在 parse 中处理用户。