Android
Data objects
Создание и запрос отношений данных в Parse для Android
19 мин
отношения на android введение используя parse, вы можете хранить объекты данных, устанавливая отношения между ними для моделирования этого поведения любой parseobject parseobject может использоваться как значение в других parseobject parseobject внутри фреймворка parse будет храниться упоминаемый объект в одном месте, чтобы поддерживать согласованность это может дать вам дополнительную мощь при построении и выполнении сложных запросов существует три основных типа отношений один к одному один к одному , устанавливающий прямые отношения между двумя объектами и только ими; один ко многим один ко многим , где один объект может быть связан с многими другими объектами; многие ко многим многие ко многим , что может создать множество сложных отношений между многими объектами существует два способа создания один ко многим один ко многим отношения в parse первый способ — использовать указатели указатели в дочернем классе, дочернем классе, что является самым быстрым способом по времени создания и запросов второй способ — использовать массивы массивы указателей указателей в родительском классе, что может привести к медленным временам запросов в зависимости от их размера из за этой проблемы с производительностью мы будем использовать только примеры с указателями существует три способа создания многие ко многим многие ко многим отношения в parse первый способ — использовать отношения отношения , что является самым быстрым способом по времени создания и запросов мы будем использовать это в этом руководстве второй способ — использовать массивы массивы указателей указателей что может привести к медленным временам запросов в зависимости от их размера третий способ — использовать jointable jointable где идея взята из классической базы данных когда существует отношение многие ко многим, мы объединяем каждый objectid objectid или указатель указатель с обеих сторон вместе, чтобы создать новую отдельную таблицу, в которой отслеживается связь этот учебник использует базовое приложение, созданное в android studio 4 1 1 с buildtoolsversion=30 0 2 buildtoolsversion=30 0 2 , compile sdk version = 30 0 2 compile sdk version = 30 0 2 и targetsdkversion 30 targetsdkversion 30 в любое время вы можете получить доступ к полному проекту android, созданному с помощью этого учебника, в наших репозиториях на github репозиторий примера на kotlin репозиторий примера на java цель наша цель понять отношения parse, создавая практическое приложение для книг вот предварительный просмотр того, что мы собираемся достичь предварительные требования чтобы завершить этот учебник, нам нужно android studio приложение, созданное на back4app примечание следуйте за учебником по созданию нового parse app чтобы узнать, как создать parse app на back4app android приложение, подключенное к back4app примечание следуйте за учебником по установке parse sdk чтобы создать проект android studio, подключенный к back4app устройство (или виртуальное устройство ) с android 4 1 (jelly bean) или новее понимание приложения для книг основной класс объекта, который вы будете использовать, это книга книга , который хранит каждую запись книги в регистрации также это другие три класса объектов издатель издатель название издателя книги, один ко многим один ко многим отношение с книга книга жанр жанр жанр книги, один ко многим один ко многим отношение с книга книга обратите внимание, что в этом примере мы будем считать, что у книги может быть только один жанр; автор автор автор книги, многие ко многим многие ко многим отношение с книга книга , так как у книги может быть более одного автора, и у автора может быть более одной книги; визуальное представление этой модели данных давайте начнем! перед следующими шагами нам нужно подключить back4app back4app к нашему приложению вам следует сохранить appid appid и clientkey clientkey из back4app back4app в файл string xml string xml и затем инициализировать parse parse в нашем файле app java app java или app kt app kt следуйте новому учебнику по parse app если вы не знаете, как инициализировать parse parse в вашем приложении или вы можете скачать проекты, ссылки на которые мы поделились выше, и отредактировать только appid appid и clientkey clientkey в соответствии с вашими требованиями 1 сохраните и перечислите связанные объекты книг на этом этапе мы увидим, как сохранить и перечислить жанры жанры , издатели издатели и авторы авторы классы, связанные с классом книга книга 1 1 сохранить и перечислить жанры мы можем зарегистрировать жанр жанр с помощью следующего фрагмента 1 private void addgenre(string name) { 2 //we are taking this name parameter from the input 3 progressdialog show(); 4 parseobject parseobject = new parseobject("genre"); 5 parseobject put("name", name); 6 parseobject saveinbackground(e > { 7 progressdialog dismiss(); 8 if (e == null) { 9 getgenres(); 10 inputgenre settext(""); 11 toast maketext(this, "genre saved successfully", toast length short) show(); 12 } else { 13 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 14 } 15 }); 16 }1 private fun addgenre(name string) { 2 //we are taking this name parameter from the input 3 progressdialog show() 4 val parseobject = parseobject("genre") 5 parseobject put("name", name) 6 parseobject saveinbackground { 7 progressdialog dismiss() 8 if (it == null) { 9 getgenres() 10 inputgenre settext("") 11 toast maketext(this, "genre saved successfully", toast length short) show() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 16 } мы можем зарегистрировать жанр жанр с помощью следующего фрагмента 1 private void getgenres() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("genre"); 4 query findinbackground((objects, e) > { 5 progressdialog dismiss(); 6 list\<parseobjectmodel> list = new arraylist<>(); 7 for (parseobject parseobject objects) { 8 list add(new parseobjectmodel(parseobject)); 9 } 10 11 genreadapter adapter = new genreadapter(list, this); 12 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 13 recyclerview\ setadapter(adapter); 14 }); 15 }1 private fun getgenres() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("genre") 4 query findinbackground { objects, e > 5 progressdialog dismiss() 6 var list mutablelist\<parseobjectmodel> = arraylist() 7 for (parseobject in objects) { 8 list add(parseobjectmodel(parseobject)) 9 } 10 val adapter = genreadapter(this, list) 11 recyclerview\ layoutmanager = linearlayoutmanager(this) 12 recyclerview\ adapter = adapter 13 } 14 } 1 2 сохранить и перечислить издателей мы можем зарегистрировать издателя издателя с помощью следующего фрагмента 1 private void addpublisher(string name) { 2 //we are taking this name parameter from the input 3 progressdialog show(); 4 parseobject parseobject = new parseobject("publisher"); 5 parseobject put("name", name); 6 parseobject saveinbackground(e > { 7 progressdialog dismiss(); 8 if (e == null) { 9 getpublishers(); 10 inputpublisher settext(""); 11 toast maketext(this, "publisher saved successfully", toast length short) show(); 12 } else { 13 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 14 } 15 }); 16 }1 private fun addpublisher(name string) { 2 //we are taking this name parameter from the input 3 progressdialog show() 4 val parseobject = parseobject("publisher") 5 parseobject put("name", name) 6 parseobject saveinbackground { 7 progressdialog dismiss() 8 if (it == null) { 9 getpublishers() 10 inputpublisher settext("") 11 toast maketext(this, "publisher saved successfully", toast length short) show() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 16 } мы можем зарегистрировать издателя издателя с помощью следующего фрагмента 1 private void getpublishers() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("publisher"); 4 query findinbackground((objects, e) > { 5 progressdialog dismiss(); 6 list\<parseobjectmodel> list = new arraylist<>(); 7 for (parseobject parseobject objects) { 8 list add(new parseobjectmodel(parseobject)); 9 } 10 11 publisheradapter adapter = new publisheradapter(list, this); 12 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 13 recyclerview\ setadapter(adapter); 14 }); 15 }1 private fun getpublishers() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("publisher") 4 query findinbackground { objects, e > 5 progressdialog dismiss() 6 val list arraylist\<parseobjectmodel> = arraylist() 7 for (parseobject in objects) { 8 list add(parseobjectmodel(parseobject)) 9 } 10 11 val adapter = publisheradapter(this, list) 12 recyclerview\ layoutmanager = linearlayoutmanager(this) 13 recyclerview\ adapter = adapter 14 } 15 } 1 3 сохранить и перечислить авторов мы можем зарегистрировать автора автора с помощью следующего фрагмента 1 private void addauthor(string name){ 2 //we are taking this name parameter from the input 3 progressdialog show(); 4 parseobject parseobject = new parseobject("author"); 5 parseobject put("name", name); 6 parseobject saveinbackground(e > { 7 progressdialog dismiss(); 8 if (e == null) { 9 getauthors(); 10 inputauthor settext(""); 11 toast maketext(this, "author saved successfully", toast length short) show(); 12 } else { 13 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 14 } 15 }); 16 }1 private fun addauthor(name string) { 2 //we are taking this name parameter from the input 3 progressdialog show() 4 val parseobject = parseobject("author") 5 parseobject put("name", name) 6 parseobject saveinbackground { 7 progressdialog dismiss() 8 if (it == null) { 9 getauthors() 10 inputauthor settext("") 11 toast maketext(this, "author saved successfully", toast length short) show() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 16 } мы можем зарегистрировать автора автора с помощью следующего фрагмента 1 private void getauthors() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("author"); 4 query findinbackground((objects, e) > { 5 progressdialog dismiss(); 6 list\<parseobjectmodel> list = new arraylist<>(); 7 for (parseobject parseobject objects) { 8 list add(new parseobjectmodel(parseobject)); 9 } 10 11 authoradapter adapter = new authoradapter(list, this); 12 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 13 recyclerview\ setadapter(adapter); 14 }); 15 }1 private fun getauthors() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("author") 4 query findinbackground { objects list\<parseobject>, e parseexception? > 5 progressdialog dismiss() 6 val list arraylist\<parseobjectmodel> = arraylist() 7 for (parseobject in objects) { 8 list add(parseobjectmodel(parseobject)) 9 } 10 val adapter = authoradapter(this, list) 11 recyclerview\ layoutmanager = linearlayoutmanager(this) 12 recyclerview\ adapter = adapter 13 } 14 } в этой части мы используем класс модели с именем parseobjectmodel parseobjectmodel в этом классе модели у нас есть parseobject parseobject переменная, чтобы иметь возможность читать данные, и переменная ischecked ischecked , которую мы будем использовать для сохранения книги на следующем шаге мы сможем легко извлечь выбранные объекты с помощью переменной ischecked ischecked вот наша parseobjectmodel parseobjectmodel модель 1 public class parseobjectmodel { 2 parseobject object; 3 boolean ischecked = false; 4 5 public parseobjectmodel(parseobject object) { 6 this object = object; 7 } 8 9 public parseobject getobject() { 10 return object; 11 } 12 13 public parseobjectmodel setobject(parseobject object) { 14 this object = object; 15 return this; 16 } 17 18 public boolean ischecked() { 19 return ischecked; 20 } 21 22 public parseobjectmodel setchecked(boolean checked) { 23 ischecked = checked; 24 return this; 25 } 26 }1 class parseobjectmodel(obj parseobject) { 2 var obj parseobject? = null 3 var ischecked boolean = false 4 5 init { 6 this obj = obj 7 } 8 } 2 сохранить объект книги и его отношения 2 1 сохранить объект книги с отношением 1\ n эта функция создаст новый книга книга в базе данных back4app с отношениями 1\ n 1 progressdialog show(); 2 book put("genre", genre); 3 book put("publisher", publisher); 4 book put("title", title); 5 book put("year", year); 6 book saveinbackground(e > { 7 progressdialog hide(); 8 if (e == null) { 9 toast maketext(addbookactivity this, "book saved successfully", toast length short) show(); 10 startactivity(new intent(addbookactivity this, booklistactivity class)); 11 finish(); 12 } else { 13 toast maketext(addbookactivity this, e getlocalizedmessage(), toast length short) show(); 14 } 15 });1 progressdialog show() 2 book put("genre", genre) 3 book put("publisher", publisher!!) 4 book put("title", title) 5 book put("year", year) 6 book saveinbackground { 7 progressdialog hide() 8 if (it == null) { 9 toast maketext(this, "book saved successfully", toast length short) show() 10 startactivity(intent(this\@addbookactivity, booklistactivity class java)) 11 finish() 12 } else { 13 toast maketext(this, it localizedmessage, toast length short) show() 14 } 15 } 2 2 сохранить объект книга с отношением n\ n эта функция создаст новый книга книга в базе данных back4app с отношениями n\ n для автор автор отношения мы находим выбранного автор/ов в адаптере authorrecyclerview authorrecyclerview и сохраняем их как parse relation parse relation 1 progressdialog show(); 2 book put("genre", genre); 3 book put("publisher", publisher); 4 book put("title", title); 5 book put("year", year); 6 7 //here we are setting book relation with getselecteditem function of bookauthoradapter 8 if (recyclerviewauthors getadapter() != null) { 9 relation = ((bookauthoradapter) recyclerviewauthors getadapter()) getselecteditems(book); 10 if (relation == null) { 11 toast maketext(this, "please select author/s", toast length short) show(); 12 return; 13 } 14 } else { 15 toast maketext(this, "something went wrong!!", toast length short) show(); 16 return; 17 } 18 19 book saveinbackground(e > { 20 progressdialog hide(); 21 if (e == null) { 22 toast maketext(addbookactivity this, "book saved successfully", toast length short) show(); 23 startactivity(new intent(addbookactivity this, booklistactivity class)); 24 finish(); 25 } else { 26 toast maketext(addbookactivity this, e getlocalizedmessage(), toast length short) show(); 27 } 28 }); 29 30 //this is the function for save author/s relation of book object this function in bookauthoradapter 31 public parserelation\<parseobject> getselecteditems(parseobject parseobject) { 32 parserelation\<parseobject> relation = parseobject getrelation("author relation"); 33 for (parseobjectmodel object this list) { 34 if (object ischecked()) 35 relation add(object getobject()); 36 } 37 return relation; 38 } 1 progressdialog show() 2 book put("genre", genre) 3 book put("publisher", publisher!!) 4 book put("title", title) 5 book put("year", year) 6 7 //here we are setting book relation with getselecteditem function of bookauthoradapter 8 9 if (recyclerviewauthors adapter != null) { 10 relation = (recyclerviewauthors adapter as bookauthoradapter) getselecteditems(book) 11 if (relation == null) { 12 toast maketext(this, "please select author/s", toast length short) show() 13 return 14 } 15 } else { 16 toast maketext(this, "something went wrong!!", toast length short) show() 17 return 18 } 19 20 book saveinbackground { 21 progressdialog hide() 22 if (it == null) { 23 toast maketext(this, "book saved successfully", toast length short) show() 24 startactivity(intent(this\@addbookactivity, booklistactivity class java)) 25 finish() 26 } else { 27 toast maketext(this, it localizedmessage, toast length short) show() 28 } 29 } 30 31 //this is the function for save author/s relation of book object this function in bookauthoradapter 32 33 fun getselecteditems(parseobject parseobject) parserelation\<parseobject>? { 34 var relation\ parserelation\<parseobject>? = parseobject getrelation("author relation") 35 for (obj in this list) { 36 if (obj ischecked) 37 relation? add(obj obj) 38 } 39 return relation 40 } 3 запросить детали книги с отношениями с помощью этих функций мы перечислим наши книги книги в соответствии с их издателями издателями сначала мы отправим запрос к классу издатель 1 progressdialog show(); 2 parsequery\<parseobject> query = new parsequery<>("publisher"); 3 query findinbackground((objects, e) > { 4 progressdialog hide(); 5 if (e == null) { 6 booklistadapter adapter = new booklistadapter(objects, this); 7 recyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 8 recyclerview\ setadapter(adapter); 9 } else { 10 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 11 } 12 });1 progressdialog show() 2 val query = parsequery\<parseobject>("publisher") 3 query findinbackground { objects list\<parseobject>?, e parseexception? > 4 progressdialog hide() 5 if (e == null) { 6 val adapter = booklistadapter(this, objects!!) 7 recyclerview\ layoutmanager = linearlayoutmanager(this) 8 recyclerview\ adapter = adapter 9 } else { 10 toast maketext(this, e localizedmessage, toast length short) show() 11 } 12 } а затем мы запрашиваем список книг книг к которым относится каждый издатель издатель 1 parseobject object = list get(position); 2 holder title settext(object getstring("name")); 3 parsequery\<parseobject> query = new parsequery<>("book"); 4 query whereequalto("publisher", object); 5 query findinbackground((objects, e) > { 6 if (e == null) { 7 booksadapter adapter = new booksadapter(objects, context); 8 holder books setlayoutmanager(new linearlayoutmanager(context)); 9 holder books setadapter(adapter); 10 } else { 11 toast maketext(context, e getlocalizedmessage(), toast length short) show(); 12 } 13 });1 val `object` = list\[position] 2 holder title text = `object` getstring("name") 3 val query = parsequery\<parseobject>("book") 4 query whereequalto("publisher", `object`) 5 query findinbackground { objects list\<parseobject>?, e parseexception? > 6 if (e == null) { 7 val adapter = booksadapter(context, objects!!) 8 holder books layoutmanager = linearlayoutmanager(context) 9 holder books adapter = adapter 10 } else { 11 toast maketext(context, e localizedmessage, toast length short) show() 12 } 13 } теперь, когда мы нажимаем на любой книгу книгу объект, мы отправляем идентификатор объекта этой книги книги с намерением на страницу, которая покажет детали этой книги книги и мы получаем все детали книги книги из базы данных, используя этот идентификатор объекта на этой странице 1 private void getbookwithdetails() { 2 progressdialog show(); 3 parsequery\<parseobject> query = new parsequery<>("book"); 4 query getinbackground(getintent() getstringextra("objectid"), (object, e) > { 5 if (e == null) { 6 booktitle settext("title " +object getstring("title")); 7 bookyear settext("year " +object getstring("year")); 8 try { 9 bookgenre settext("genre " +object getparseobject("genre") fetchifneeded() getstring("name")); 10 } catch (parseexception parseexception) { 11 parseexception printstacktrace(); 12 } 13 try { 14 bookpublisher settext("publisher " + object getparseobject("publisher") fetchifneeded() getstring("name")); 15 } catch (parseexception parseexception) { 16 parseexception printstacktrace(); 17 } 18 19 object getrelation("author relation") getquery() findinbackground((objects, e1) > { 20 progressdialog hide(); 21 if (e1 == null) { 22 bookdetailauthoradapter adapter = new bookdetailauthoradapter(objects, this); 23 authorrecyclerview\ setlayoutmanager(new linearlayoutmanager(this)); 24 authorrecyclerview\ setadapter(adapter); 25 } else { 26 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 27 } 28 }); 29 } else { 30 progressdialog hide(); 31 toast maketext(this, e getlocalizedmessage(), toast length short) show(); 32 } 33 }); 34 }1 private fun getbookwithdetails() { 2 progressdialog show() 3 val query = parsequery\<parseobject>("book") 4 5 query getinbackground(intent getstringextra("objectid")) { `object`, e > 6 if (e == null) { 7 booktitle text = "title " + `object` getstring("title") 8 bookyear text = "year " + `object` getstring("year") 9 try { 10 bookgenre text = "genre " + `object` getparseobject("genre")? fetchifneeded\<parseobject>()? getstring("name") 11 } catch (parseexception parseexception) { 12 parseexception printstacktrace() 13 } 14 try { 15 bookpublisher text = 16 "publisher " + `object` getparseobject("publisher")? fetchifneeded\<parseobject>()? getstring("name") 17 } catch (parseexception parseexception) { 18 parseexception printstacktrace() 19 } 20 21 `object` getrelation\<parseobject>("author relation") query findinbackground { objects, e1 > 22 progressdialog hide() 23 if (e1 == null) { 24 val adapter = bookdetailauthoradapter(this, objects) 25 authorrecyclerview\ layoutmanager = linearlayoutmanager(this) 26 authorrecyclerview\ adapter = adapter 27 } else { 28 toast maketext(this, e1 localizedmessage, toast length short) show() 29 } 30 } 31 } else { 32 progressdialog hide() 33 toast maketext(this, e localizedmessage, toast length short) show() 34 } 35 } 36 } сделано! на данный момент мы изучили связи parse связи parse на android android