Maîtriser les relations de données Parse pour Android
19 min
relations sur android introduction en utilisant parse, vous pouvez stocker des objets de données établissant des relations entre eux pour modéliser ce comportement, tout \<font color="#2166ae">parseobject\</font> peut être utilisé comme valeur dans d'autres \<font color="#2166ae">parseobject\</font> en interne, le framework parse stockera l'objet référencé à un seul endroit, pour maintenir la cohérence cela peut vous donner un pouvoir supplémentaire lors de la construction et de l'exécution de requêtes complexes il existe trois principaux types de relations \<font color="#2166ae">un à un\</font> , établissant des relations directes entre deux objets et seulement eux; \<font color="#2166ae">un à plusieurs\</font> , où un objet peut être lié à plusieurs autres objets; \<font color="#2166ae">plusieurs à plusieurs\</font> , ce qui peut créer de nombreuses relations complexes entre de nombreux objets il existe deux façons de créer une \<font color="#2166ae">relation un à plusieurs\</font> dans parse la première consiste à utiliser les \<font color="#2166ae">pointeurs\</font> dans \<font color="#2166ae">classe enfant,\</font> qui est la plus rapide en termes de création et de temps de requête la seconde consiste à utiliser des \<font color="#2166ae">tableaux\</font> de \<font color="#2166ae">pointeurs\</font> dans la classe parent, ce qui peut entraîner des temps de requête lents en fonction de leur taille en raison de ce problème de performance, nous utiliserons uniquement des exemples de pointeurs il existe trois façons de créer une \<font color="#2166ae">relation plusieurs à plusieurs\</font> dans parse la première consiste à utiliser les \<font color="#2166ae">relations\</font> , qui est la plus rapide en termes de création et de temps de requête nous utiliserons cela dans ce guide la seconde consiste à utiliser des \<font color="#2166ae">tableaux\</font> de \<font color="#2166ae">pointeurs\</font> qui peuvent entraîner des temps de requête lents en fonction de leur taille la troisième consiste à utiliser \<font color="#2166ae">jointable\</font> où l'idée provient de la base de données classique lorsqu'il y a une relation plusieurs à plusieurs, nous combinons chaque \<font color="#2166ae">objectid\</font> ou \<font color="#2166ae">pointeur\</font> des deux côtés pour créer une nouvelle table séparée dans laquelle la relation est suivie ce tutoriel utilise une application de base créée dans android studio 4 1 1 avec \<font color="#2166ae">buildtoolsversion=30 0 2\</font> , \<font color="#2166ae">compile sdk version = 30 0 2\</font> et \<font color="#2166ae">targetsdkversion 30\</font> à tout moment, vous pouvez accéder au projet android complet construit avec ce tutoriel sur nos dépôts github dépôt d'exemple kotlin https //github com/templates back4app/android parse sdk kotlin dépôt d'exemple java https //github com/templates back4app/android parse sdk java objectif notre objectif est de comprendre les relations parse en créant une application pratique de livres voici un aperçu de ce que nous allons réaliser prérequis pour compléter ce tutoriel, nous avons besoin de android studio https //developer android com/studio/index html une application créée sur back4app remarque suivez le tutoriel de nouvelle application parse https //www back4app com/docs/get started/new parse app pour apprendre à créer une application parse sur back4app une application android connectée à back4app remarque suivez le tutoriel d'installation du sdk parse https //www back4app com/docs/android/parse android sdk pour créer un projet android studio connecté à back4app un appareil (ou appareil virtuel https //developer android com/studio/run/managing avds html ) fonctionnant sous android 4 1 (jelly bean) ou version ultérieure comprendre l'application de livre la classe d'objet principale que vous utiliserez est la \<font color="#2166ae">livre\</font> classe, stockant chaque entrée de livre dans l'enregistrement de plus, voici les trois autres classes d'objet \<font color="#2166ae">éditeur\</font> nom de l'éditeur du livre, \<font color="#2166ae">un à plusieurs\</font> relation avec \<font color="#2166ae">livre\</font> \<font color="#2166ae">genre\</font> genre du livre, \<font color="#2166ae">un à plusieurs\</font> relation avec \<font color="#2166ae">livre\</font> notez que pour cet exemple, nous considérerons qu'un livre ne peut avoir qu'un seul genre ; \<font color="#2166ae">auteur\</font> auteur du livre, \<font color="#2166ae">plusieurs à plusieurs\</font> relation avec \<font color="#2166ae">livre\</font> , puisque un livre peut avoir plus d'un auteur et un auteur peut avoir plus d'un livre également ; une représentation visuelle de ce modèle de données commençons! avant les prochaines étapes, nous devons connecter \<font color="#2166ae">back4app\</font> à notre application vous devez sauvegarder le \<font color="#2166ae">appid\</font> et \<font color="#2166ae">clientkey\</font> depuis le \<font color="#2166ae">back4app\</font> dans le fichier \<font color="#2166ae">string xml\</font> et ensuite init \<font color="#2166ae">parse\</font> dans notre \<font color="#2166ae">app java\</font> ou \<font color="#2166ae">app kt\</font> fichier suivez le nouveau tutoriel d'application parse https //www back4app com/docs/android/parse android sdk si vous ne savez pas comment init \<font color="#2166ae">parse\</font> à votre application ou vous pouvez télécharger les projets dont nous avons partagé les liens github ci dessus et modifier uniquement les \<font color="#2166ae">appid\</font> et \<font color="#2166ae">clientkey\</font> selon vos besoins 1 sauvegarder et lister les objets liés aux livres dans cette étape, nous allons voir comment enregistrer et lister les \<font color="#2166ae">genres\</font> , \<font color="#2166ae">éditeurs\</font> et \<font color="#2166ae">auteurs\</font> classes liées à la \<font color="#2166ae">livre\</font> classe 1 1 enregistrer et lister les genres nous pouvons enregistrer un \<font color="#2166ae">genre\</font> en utilisant le code suivant 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 } nous pouvons enregistrer un \<font color="#2166ae">genre\</font> en utilisant le snippet suivant 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 enregistrer et lister les éditeurs nous pouvons enregistrer un \<font color="#2166ae">éditeur\</font> en utilisant le snippet suivant 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 } nous pouvons enregistrer un \<font color="#2166ae">éditeur\</font> en utilisant le snippet suivant 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 enregistrer et lister les auteurs nous pouvons enregistrer un \<font color="#2166ae">auteur\</font> en utilisant le snippet suivant 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 } nous pouvons enregistrer un \<font color="#2166ae">auteur\</font> en utilisant le snippet suivant 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 } dans cette partie, nous utilisons une classe modèle nommée \<font color="#2166ae">parseobjectmodel\</font> dans cette classe modèle, nous avons une \<font color="#2166ae">parseobject\</font> variable pour pouvoir lire les données, et la \<font color="#2166ae">ischecked\</font> variable, que nous utiliserons pour enregistrer le livre dans l'étape suivante nous pourrons facilement récupérer les objets sélectionnés avec la \<font color="#2166ae">ischecked\</font> variable voici notre \<font color="#2166ae">parseobjectmodel\</font> modèle 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 enregistrer un objet livre et ses relations 2 1 enregistrer un objet livre avec une relation 1\ n cette fonction va créer un nouveau \<font color="#2166ae">livre\</font> dans la base de données back4app avec des relations 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 enregistrer un objet livre avec une relation n\ n cette fonction va créer un nouveau \<font color="#2166ae">livre\</font> dans la base de données back4app avec des relations n\ n pour la \<font color="#2166ae">auteur\</font> relation, nous trouvons les auteur/s sélectionnés dans l'adaptateur du \<font color="#2166ae">authorrecyclerview\</font> et les enregistrons comme \<font color="#2166ae">relation parse\</font> 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 interroger les détails du livre avec des relations avec ces fonctions, nous allons lister nos \<font color="#2166ae">livres\</font> selon leurs \<font color="#2166ae">éditeurs\</font> tout d'abord, nous lançons une requête à la classe éditeur 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 } et ensuite, nous interrogeons pour lister les \<font color="#2166ae">livres\</font> auxquels chaque \<font color="#2166ae">éditeur\</font> est lié 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 } maintenant, lorsque nous cliquons sur un \<font color="#2166ae">livre\</font> objet, nous envoyons l'id de l'objet de ce \<font color="#2166ae">livre\</font> avec une intention vers la page qui affichera les détails de ce \<font color="#2166ae">livre\</font> et nous obtenons tous les détails du \<font color="#2166ae">livre \</font> de la base de données en utilisant cet id d'objet sur cette page 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 } c'est fait ! à ce stade, nous avons appris \<font color="#2166ae">les relations parse\</font> sur \<font color="#2166ae">android\</font>