ReactJS
Data objects
Реляционные запросы в Parse: Реализация на React
10 мин
реляционный запрос в react с использованием parse введение в этом руководстве вы будете выполнять реляционные запросы в parse и реализовывать компонент react, используя эти запросы вы узнаете, как настроить и запрашивать реалистичные данные с помощью back4app и react предварительные условия чтобы завершить это руководство, вам потребуется приложение react, созданное и подключенное к back4app если вы хотите запустить пример проекта из этого руководства, вам следует настроить библиотеку ant design ant design цель запрос реляционных данных, хранящихся на back4app, из приложения react 1 понимание класса parse query любая операция запроса parse использует тип объекта parse query parse query , который поможет вам извлекать конкретные данные из вашей базы данных на протяжении всего вашего приложения важно знать, что parse query parse query разрешится только после вызова метода извлечения (например, parse query find parse query find или parse query first parse query first ), поэтому запрос может быть настроен, и несколько модификаторов могут быть связаны перед фактическим вызовом чтобы создать новый parse query parse query , вам нужно передать в качестве параметра желаемый parse object parse object подкласс, который будет содержать результаты вашего запроса пример запроса можно увидеть ниже, в котором запрашивается вымышленный книга книга подкласс 1 // this will create your query 2 let parsequery = new parse query("book"); 3 // the query will resolve only after calling this method 4 let queryresult = await parsequery find(); вы можете узнать больше о parse query parse query классе здесь в официальной документации https //parseplatform org/parse sdk js/api/master/parse query html 2 сохраните некоторые данные на back4app давайте создадим ассортимент классов, которые будут целью наших запросов в этом руководстве классы автор автор , книга книга , издатель издатель и книжный магазин книжный магазин , в котором книга книга имеет отношение 1\ n с издатель издатель и n\ n с автор автор , а книжный магазин книжный магазин имеет отношение n\ n с книга книга в консоли parse js можно выполнять код javascript напрямую, запрашивая и обновляя содержимое вашей базы данных приложения с помощью команд js sdk запустите код ниже из вашей js консоли и вставьте данные на back4app вот как выглядит js консоль на вашей панели управления продолжайте и создайте классы с следующим примерным содержимым 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 // publishers 16 const publishera = new parse object('publisher'); 17 publishera set('name', 'acacia publishings'); 18 await publishera save(); 19	 20 const publisherb = new parse object('publisher'); 21 publisherb set('name', 'birch distributions'); 22 await publisherb save(); 23	 24 // books 25 const booka = new parse object('book'); 26 booka set('title', 'a love story'); 27 booka set('publisher', publishera); 28 booka set('publishingdate', new date('05/07/1998')); 29 const bookarelation = booka relation("authors"); 30 bookarelation add(authora); 31 await booka save(); 32	 33 const bookb = new parse object('book'); 34 bookb set('title', 'benevolent elves'); 35 bookb set('publisher', publisherb); 36 bookb set('publishingdate', new date('11/31/2008')); 37 const bookbrelation = bookb relation("authors"); 38 bookbrelation add(authorb); 39 await bookb save(); 40	 41 const bookc = new parse object('book'); 42 bookc set('title', 'can you believe it?'); 43 bookc set('publisher', publisherb); 44 bookc set('publishingdate', new date('08/21/2018')); 45 const bookcrelation = bookc relation("authors"); 46 bookcrelation add(authora); 47 bookcrelation add(authorc); 48 await bookc save(); 49	 50 // bookstore 51 const bookstorea = new parse object('bookstore'); 52 bookstorea set('name', 'books of love'); 53 const bookstorearelation = bookstorea relation("books"); 54 bookstorearelation add(booka); 55 await bookstorea save(); 56	 57 const bookstoreb = new parse object('bookstore'); 58 bookstoreb set('name', 'fantasy books'); 59 const bookstorebrelation = bookstoreb relation("books"); 60 bookstorebrelation add(bookb); 61 await bookstoreb save(); 62	 63 const bookstorec = new parse object('bookstore'); 64 bookstorec set('name', 'general books'); 65 const bookstorecrelation = bookstorec relation("books"); 66 bookstorecrelation add(booka); 67 bookstorecrelation add(bookc); 68 await bookstorec save(); 69	 70 console log('success'); 3 запрос данных теперь, когда вы заполнили все классы, мы можем выполнить некоторые реляционные запросы давайте начнем с фильтрации книги книги по издателю издателю , ища те, которые принадлежат издателю “издательство акация” (или “издатель а”) с использованием базового parse query equalto parse query equalto метода 1 // get publishera object 2 const publisheraquery = new parse query('publisher'); 3 publisheraquery equalto('name', 'acacia publishings'); 4 const publishera = await publisheraquery first(); 5	 6 // query books with publishera 7 const bookquery = new parse query('book'); 8 bookquery equalto('publisher', publishera); 9 let queryresults = await bookquery find(); 10	 11 // let's show the results 12 for (let result of queryresults) { 13 // you access `parse objects` attributes by using ` get` 14 console log(result get('title')); 15 }; теперь давайте запросим, какие bookstore bookstore объекты содержат book book объекты с датой публикации позже 01/01/2010, используя внутренний запрос с помощью parse query greaterthan parse query greaterthan метода, а затем метод parse query matchesquery parse query matchesquery 1 // create inner book query 2 const bookquery = new parse query('book'); 3 bookquery greaterthan('publishingdate', new date('01/01/2010')); 4	 5 // query bookstore using inner book query 6 const bookstorequery = new parse query('bookstore'); 7 bookstorequery matchesquery('books', bookquery); 8 let queryresults = await bookstorequery find(); 9	 10 // let's show the results 11 for (let result of queryresults) { 12 // you access `parse objects` attributes by using ` get` 13 console log(result get('name')); 14 }; теперь давайте создадим более сложный реляционный запрос, ищущий книжные магазины книжные магазины объекты, которые имеют как минимум одну книгу книгу написанную автором автором “аарон писатель” (или “автора”), используя равно равно и matchesquery matchesquery 1 // get authora object 2 const authoraquery = new parse query('author'); 3 authoraquery equalto('name', 'aaron writer'); 4 const authora = await authoraquery first(); 5	 6 // create inner book query 7 const bookquery = new parse query('book'); 8 bookquery equalto('authors', authora); 9	 10 // query bookstore using inner book query 11 const bookstorequery = new parse query('bookstore'); 12 bookstorequery matchesquery('books', bookquery); 13 let queryresults = await bookstorequery find(); 14	 15 // let's show the results 16 for (let result of queryresults) { 17 // you access `parse objects` attributes by using ` get` 18 console log(result get('name')); 19 }; 4 запрос из компонента react теперь давайте используем наши примерные запросы внутри компонента в react, с простым интерфейсом, имеющим список, показывающий результаты, а также кнопки для вызова запросов вот как выглядит код компонента, обратите внимание на doquery doquery функции, содержащие примерный код из предыдущего javascript 1 import react, { usestate } from 'react'; 2 import parse from 'parse/dist/parse min js'; 3 import ' /app css'; 4 import { button, divider } from 'antd'; 5 import { closeoutlined, searchoutlined } from '@ant design/icons'; 6	 7 export const queryrelational = () => { 8 // state variable 9 const \[queryresults, setqueryresults] = usestate(); 10	 11 const doquerya = async function () { 12 // get publishera object 13 const publisheraquery = new parse query('publisher'); 14 publisheraquery equalto('name', 'acacia publishings'); 15 const publishera = await publisheraquery first(); 16	 17 // query books with publishera 18 const bookquery = new parse query('book'); 19 bookquery equalto('publisher', publishera); 20	 21 try { 22 let results = await bookquery find(); 23 setqueryresults(results); 24 return true; 25 } catch (error) { 26 // error can be caused by lack of internet connection 27 alert(`error! ${error message}`); 28 return false; 29 } 30 }; 31	 32 const doqueryb = async function () { 33 // create inner book query 34 const bookquery = new parse query('book'); 35 bookquery greaterthan('publishingdate', new date('01/01/2010')); 36	 37 // query bookstore using inner book query 38 const bookstorequery = new parse query('bookstore'); 39 bookstorequery matchesquery('books', bookquery); 40	 41 try { 42 let results = await bookstorequery find(); 43 setqueryresults(results); 44 return true; 45 } catch (error) { 46 // error can be caused by lack of internet connection 47 alert(`error! ${error message}`); 48 return false; 49 } 50 }; 51	 52 const doqueryc = async function () { 53 // get authora object 54 const authoraquery = new parse query('author'); 55 authoraquery equalto('name', 'aaron writer'); 56 const authora = await authoraquery first(); 57	 58 // create inner book query 59 const bookquery = new parse query('book'); 60 bookquery equalto('authors', authora); 61	 62 // query bookstore using inner book query 63 const bookstorequery = new parse query('bookstore'); 64 bookstorequery matchesquery('books', bookquery); 65	 66 try { 67 let results = await bookstorequery find(); 68 setqueryresults(results); 69 return true; 70 } catch (error) { 71 // error can be caused by lack of internet connection 72 alert(`error! ${error message}`); 73 return false; 74 } 75 }; 76	 77 const clearqueryresults = async function () { 78 setqueryresults(undefined); 79 return true; 80 }; 81	 82 return ( 83 \<div> 84 \<div classname="header"> 85 \<img 86 classname="header logo" 87 alt="back4app logo" 88 src={ 89 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 90 } 91 /> 92 \<p classname="header text bold">{'react on back4app'}\</p> 93 \<p classname="header text">{'relational queries'}\</p> 94 \</div> 95 \<div classname="container"> 96 \<div classname="flex between"> 97 \<h2 classname="heading">{'query list'}\</h2> 98 \<div classname="flex"> 99 \<button 100 onclick={() => doquerya()} 101 type="primary" 102 classname="heading button" 103 color={'#208aec'} 104 icon={\<searchoutlined />} 105 > 106 query a 107 \</button> 108 \<button 109 onclick={() => doqueryb()} 110 type="primary" 111 classname="heading button" 112 color={'#208aec'} 113 icon={\<searchoutlined />} 114 > 115 query b 116 \</button> 117 \<button 118 onclick={() => doqueryc()} 119 type="primary" 120 classname="heading button" 121 color={'#208aec'} 122 icon={\<searchoutlined />} 123 > 124 query c 125 \</button> 126 \<button 127 onclick={() => clearqueryresults()} 128 type="primary" 129 classname="heading button" 130 color={'#208aec'} 131 icon={\<closeoutlined />} 132 > 133 clear results 134 \</button> 135 \</div> 136 \</div> 137 \<divider /> 138 \<div classname="flex between"> 139 \<div classname="flex child"> 140 {/ query list /} 141 {queryresults !== undefined && 142 queryresults map((result, index) => ( 143 \<div classname="list item" key={`${index}`}> 144 \<p classname="list item title">{`${ 145 result get('name') !== undefined 146 ? result get('name') 147 result get('title') 148 }`}\</p> 149 \</div> 150 ))} 151 {queryresults !== undefined && queryresults length <= 0 ? ( 152 \<p>{'no results here!'}\</p> 153 ) null} 154 \</div> 155 \</div> 156 \</div> 157 \</div> 158 ); 159 }; typescript 1 import react, { usestate, fc, reactelement } from 'react'; 2 import ' /app css'; 3 import { button, divider } from 'antd'; 4 import { closeoutlined, searchoutlined } from '@ant design/icons'; 5 const parse = require('parse/dist/parse min js'); 6	 7 export const queryrelational fc<{}> = () reactelement => { 8 // state variable 9 const \[queryresults, setqueryresults] = usestate\<parse object\[]>(); 10	 11 const doquerya = async function () promise\<boolean> { 12 // get publishera object 13 const publisheraquery parse query = new parse query('publisher'); 14 publisheraquery equalto('name', 'acacia publishings'); 15 const publishera parse object | undefined = await publisheraquery first(); 16	 17 // query books with publishera 18 const bookquery parse query = new parse query('book'); 19 bookquery equalto('publisher', publishera); 20	 21 try { 22 let results parse object\[] = await bookquery find(); 23 setqueryresults(results); 24 return true; 25 } catch (error) { 26 // error can be caused by lack of internet connection 27 alert(`error! ${error message}`); 28 return false; 29 } 30 }; 31	 32 const doqueryb = async function () promise\<boolean> { 33 // create inner book query 34 const bookquery parse query = new parse query('book'); 35 bookquery greaterthan('publishingdate', new date('01/01/2010')); 36	 37 // query bookstore using inner book query 38 const bookstorequery parse query = new parse query('bookstore'); 39 bookstorequery matchesquery('books', bookquery); 40	 41 try { 42 let results parse object\[] = await bookstorequery find(); 43 setqueryresults(results); 44 return true; 45 } catch (error) { 46 // error can be caused by lack of internet connection 47 alert(`error! ${error message}`); 48 return false; 49 } 50 }; 51	 52 const doqueryc = async function () promise\<boolean> { 53 // get authora object 54 const authoraquery parse query = new parse query('author'); 55 authoraquery equalto('name', 'aaron writer'); 56 const authora parse object | undefined = await authoraquery first(); 57	 58 // create inner book query 59 const bookquery parse query = new parse query('book'); 60 bookquery equalto('authors', authora); 61	 62 // query bookstore using inner book query 63 const bookstorequery parse query = new parse query('bookstore'); 64 bookstorequery matchesquery('books', bookquery); 65	 66 try { 67 let results parse object\[] = await bookstorequery find(); 68 setqueryresults(results); 69 return true; 70 } catch (error) { 71 // error can be caused by lack of internet connection 72 alert(`error! ${error message}`); 73 return false; 74 } 75 }; 76	 77 const clearqueryresults = async function () promise\<boolean> { 78 setqueryresults(undefined); 79 return true; 80 }; 81	 82 return ( 83 \<div> 84 \<div classname="header"> 85 \<img 86 classname="header logo" 87 alt="back4app logo" 88 src={ 89 'https //blog back4app com/wp content/uploads/2019/05/back4app white logo 500px png' 90 } 91 /> 92 \<p classname="header text bold">{'react on back4app'}\</p> 93 \<p classname="header text">{'relational queries'}\</p> 94 \</div> 95 \<div classname="container"> 96 \<div classname="flex between"> 97 \<h2 classname="heading">{'query list'}\</h2> 98 \<div classname="flex"> 99 \<button 100 onclick={() => doquerya()} 101 type="primary" 102 classname="heading button" 103 color={'#208aec'} 104 icon={\<searchoutlined />} 105 > 106 query a 107 \</button> 108 \<button 109 onclick={() => doqueryb()} 110 type="primary" 111 classname="heading button" 112 color={'#208aec'} 113 icon={\<searchoutlined />} 114 > 115 query b 116 \</button> 117 \<button 118 onclick={() => doqueryc()} 119 type="primary" 120 classname="heading button" 121 color={'#208aec'} 122 icon={\<searchoutlined />} 123 > 124 query c 125 \</button> 126 \<button 127 onclick={() => clearqueryresults()} 128 type="primary" 129 classname="heading button" 130 color={'#208aec'} 131 icon={\<closeoutlined />} 132 > 133 clear results 134 \</button> 135 \</div> 136 \</div> 137 \<divider /> 138 \<div classname="flex between"> 139 \<div classname="flex child"> 140 {/ query list /} 141 {queryresults !== undefined && 142 queryresults map((result parse object, index number) => ( 143 \<div classname="list item" key={`${index}`}> 144 \<p classname="list item title">{`${result get('name') !== undefined ? result get('name') result get('title')}`}\</p> 145 \</div> 146 ))} 147 {queryresults !== undefined && 148 queryresults length <= 0 ? ( 149 \<p>{'no results here!'}\</p> 150 ) null} 151 \</div> 152 \</div> 153 \</div> 154 \</div> 155 ); 156 }; также добавьте эти классы в ваш app css app css файл, чтобы полностью отобразить макет компонента app css 1 @import ' antd/dist/antd css'; 2	 3 app { 4 text align center; 5 } 6	 7 html { 8 box sizing border box; 9 outline none; 10 overflow auto; 11 } 12	 13 , 14 before, 15 after { 16 margin 0; 17 padding 0; 18 box sizing inherit; 19 } 20	 21 h1, 22 h2, 23 h3, 24 h4, 25 h5, 26 h6 { 27 margin 0; 28 font weight bold; 29 } 30	 31 p { 32 margin 0; 33 } 34	 35 body { 36 margin 0; 37 background color #fff; 38 } 39	 40 container { 41 width 100%; 42 max width 900px; 43 margin auto; 44 padding 20px 0; 45 text align left; 46 } 47	 48 header { 49 align items center; 50 padding 25px 0; 51 background color #208aec; 52 } 53	 54 header logo { 55 height 55px; 56 margin bottom 20px; 57 object fit contain; 58 } 59	 60 header text bold { 61 margin bottom 3px; 62 color rgba(255, 255, 255, 0 9); 63 font size 16px; 64 font weight bold; 65 } 66	 67 header text { 68 color rgba(255, 255, 255, 0 9); 69 font size 15px; 70 } 71	 72 heading { 73 font size 22px; 74 } 75	 76 flex { 77 display flex; 78 } 79	 80 flex between { 81 display flex; 82 justify content space between; 83 } 84	 85 flex child { 86 flex 0 0 45%; 87 } 88	 89 heading button { 90 margin left 12px; 91 } 92	 93 list item { 94 padding bottom 15px; 95 margin bottom 15px; 96 border bottom 1px solid rgba(0,0,0,0 06); 97 text align left; 98 } 99	 100 list item title { 101 color rgba(0,0,0,0 87); 102 font size 17px; 103 } вот как компонент должен выглядеть после рендеринга и запроса с помощью одной из функций запроса заключение в конце этого руководства вы узнали, как работают реляционные запросы в parse и как выполнять их на back4app из приложения react в следующем руководстве вы узнаете, как работать с пользователями в parse