Flutter
...
Data Queries
Consultas Relacionais Avançadas com QueryBuilder no Flutter
12 min
analisar consulta relacional no flutter introdução você já viu como armazenar objetos de dados relacionais usando os tipos de dados parse pointer e parse relations você aprendeu que no parse é possível usar qualquer parseobject como um valor em outro parseobject, estabelecendo uma relação entre eles internamente, o framework parse armazenará o objeto referido em apenas um lugar para manter a consistência isso pode lhe dar um poder extra ao construir e executar consultas complexas além disso, você já aprendeu como usar um querybuilder com get pode recuperar um único parseobject do back4app existem muitas outras maneiras de recuperar dados com querybuilder neste guia, você irá se aprofundar na classe querybuilder e ver os métodos que pode usar para construir consultas relacionais você usará uma classe de banco de dados simples com alguns dados simulados para realizar as consultas usando flutter no back4app pré requisitos para completar este tutorial, você precisará android studio https //developer android com/studio ou vs code instalado (com plugins dart e flutter) um app criado no back4app nota siga o tutorial de novo app parse para aprender como criar um app parse no back4app um app flutter conectado ao back4app nota siga o instalar o sdk parse no projeto flutter para criar um projeto flutter conectado ao back4app um dispositivo (ou dispositivo virtual) executando android ou ios objetivo consultar dados relacionais armazenados no back4app a partir de um app flutter 1 entendendo a classe querybuilder qualquer operação de consulta parse usa o tipo de objeto querybuilder, que ajudará você a recuperar dados específicos do seu banco de dados ao longo do seu app para criar um novo querybuilder, você precisa passar como parâmetro a subclasse parseobject desejada, que é a que conterá os resultados da sua consulta é crucial saber que um querybuilder só será resolvido após chamar um método de consulta retrieve, então uma consulta pode ser configurada e vários modificadores podem ser encadeados antes de realmente serem chamados 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 } você pode ler mais sobre a classe querybuilder aqui na documentação oficial usando o console javascript no back4app dentro do painel da sua aplicação back4app, você encontrará um console de api muito útil no qual pode executar código javascript diretamente neste guia, você usará para armazenar objetos de dados no back4app no painel principal do seu app, vá para core >api console >javascript 2 salvar dados no back4app para executar as consultas neste guia, você precisará primeiro preencher seu app com alguns dados as classes são autor , livro , editora e livraria qual livro tem uma 1\ n relação com editora e n\ n com autor , e livraria tem uma n\ n relação com livro aqui está o parse object código de criação de classes, então vá em frente e execute o no seu console de 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'); após executar este código, você deve agora ter uma classe author, publisher, book e bookstore em seu banco de dados sua nova classe deve parecer assim agora vamos dar uma olhada em exemplos de cada método querybuilder, juntamente com breves explicações sobre o que eles fazem 3 consultar os dados agora que você tem uma classe populada, podemos realizar algumas consultas relacionais agora que você populou todas as classes, podemos realizar algumas consultas relacionais nelas vamos começar filtrando os resultados de livros pelo editor, buscando aqueles que pertencem ao editor “acacia publishings” (ou “editor a”) com o pointer relacional usando o método básico 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 } agora vamos consultar quais objetos bookstore contêm objetos book com data de publicação maior que 01/01/2010, usando uma consulta interna com o método wheregreaterthan e depois o método 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 } agora vamos criar outra consulta, procurando por autores que estão relacionados com o livro can you believe it ?, usando 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 consulta do flutter agora vamos usar nossas consultas de exemplo dentro de um aplicativo flutter, com uma interface simples que possui uma lista mostrando os resultados e também 3 botões para chamar as consultas abra seu projeto flutter, vá para o arquivo main dart, limpe todo o código e substitua o por 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 } encontre seu id de aplicação e credenciais de chave do cliente navegando até o painel do seu aplicativo em site do back4app https //www back4app com/ atualize seu código em main dart com os valores do applicationid e clientkey do seu projeto no back4app keyapplicationid = id do app keyclientkey = chave do cliente execute o projeto, e o aplicativo será carregado conforme mostrado na imagem conclusão no final deste guia, você aprendeu como as consultas relacionais funcionam no parse e como realizá las no back4app a partir de um aplicativo flutter no próximo guia, você aprenderá como trabalhar com usuários no parse