Crea e Interroga Relazioni Parse su Android
19 min
relazioni su android introduzione utilizzando parse, puoi memorizzare oggetti di dati stabilendo relazioni tra di essi per modellare questo comportamento, qualsiasi \<font color="#2166ae">parseobject\</font> può essere utilizzato come valore in altri \<font color="#2166ae">parseobject\</font> internamente, il framework parse memorizzerà l'oggetto a cui si fa riferimento in un solo posto, per mantenere la coerenza questo può darti ulteriore potere quando costruisci ed esegui query complesse ci sono tre principali tipi di relazione \<font color="#2166ae">uno a uno\</font> , stabilendo relazioni dirette tra due oggetti e solo tra di essi; \<font color="#2166ae">uno a molti\</font> , dove un oggetto può essere correlato a molti altri oggetti; \<font color="#2166ae">molti a molti\</font> , che può creare molte relazioni complesse tra molti oggetti ci sono due modi per creare una \<font color="#2166ae">relazione uno a molti\</font> in parse il primo è utilizzare i \<font color="#2166ae">puntatori\</font> in \<font color="#2166ae">classe figlia,\</font> che è il più veloce in termini di creazione e tempo di query il secondo è utilizzare \<font color="#2166ae">array\</font> di \<font color="#2166ae">puntatori\</font> nella classe genitore, che può portare a tempi di query lenti a seconda delle loro dimensioni a causa di questo problema di prestazioni, utilizzeremo solo esempi di puntatori ci sono tre modi per creare una \<font color="#2166ae">relazione molti a molti\</font> in parse il primo è utilizzare le \<font color="#2166ae">relazioni\</font> , che è il più veloce in termini di creazione e tempo di query utilizzeremo questo in questa guida il secondo è utilizzare \<font color="#2166ae">array\</font> di \<font color="#2166ae">puntatori\</font> che possono portare a tempi di query lenti a seconda delle loro dimensioni il terzo è utilizzare \<font color="#2166ae">jointable\</font> dove l'idea proviene dai database classici quando c'è una relazione molti a molti, combiniamo ogni \<font color="#2166ae">objectid\</font> o \<font color="#2166ae">puntatore\</font> da entrambi i lati insieme per costruire una nuova tabella separata in cui viene tracciata la relazione questo tutorial utilizza un'app di base creata in android studio 4 1 1 con \<font color="#2166ae">buildtoolsversion=30 0 2\</font> , \<font color="#2166ae">compile sdk version = 30 0 2\</font> e \<font color="#2166ae">targetsdkversion 30\</font> in qualsiasi momento, puoi accedere al progetto android completo costruito con questo tutorial nei nostri repository github repository di esempio kotlin https //github com/templates back4app/android parse sdk kotlin repository di esempio java https //github com/templates back4app/android parse sdk java obiettivo il nostro obiettivo è comprendere le relazioni parse creando un'app pratica per i libri ecco un'anteprima di ciò che realizzeremo requisiti per completare questo tutorial, abbiamo bisogno di android studio https //developer android com/studio/index html un'app creata su back4app nota segui il tutorial nuova app parse https //www back4app com/docs/get started/new parse app per imparare a creare un'app parse su back4app un'app android collegata a back4app nota segui il tutorial installazione sdk parse https //www back4app com/docs/android/parse android sdk per creare un progetto android studio collegato a back4app un dispositivo (o dispositivo virtuale https //developer android com/studio/run/managing avds html ) che esegue android 4 1 (jelly bean) o versioni successive comprendere l'app libri la classe principale che utilizzerai è la \<font color="#2166ae">libro\</font> classe, che memorizza ogni voce di libro nella registrazione inoltre, queste sono le altre tre classi di oggetti \<font color="#2166ae">editore\</font> nome dell'editore del libro, \<font color="#2166ae">uno a molti\</font> relazione con \<font color="#2166ae">libro\</font> \<font color="#2166ae">genere\</font> genere del libro, \<font color="#2166ae">uno a molti\</font> relazione con \<font color="#2166ae">libro\</font> nota che per questo esempio considereremo che un libro può avere solo un genere; \<font color="#2166ae">autore\</font> autore del libro, \<font color="#2166ae">molti a molti\</font> relazione con \<font color="#2166ae">libro\</font> , poiché un libro può avere più di un autore e un autore può avere più di un libro; una rappresentazione visiva di questo modello di dati iniziamo! prima dei prossimi passi, dobbiamo connettere \<font color="#2166ae">back4app\</font> alla nostra applicazione dovresti salvare il \<font color="#2166ae">appid\</font> e \<font color="#2166ae">clientkey\</font> dal \<font color="#2166ae">back4app\</font> nel file \<font color="#2166ae">string xml\</font> e poi inizializza \<font color="#2166ae">parse\</font> nel nostro \<font color="#2166ae">app java\</font> o \<font color="#2166ae">app kt\</font> file segui il nuovo tutorial per l'app parse https //www back4app com/docs/android/parse android sdk se non sai come inizializzare \<font color="#2166ae">parse\</font> nella tua app oppure puoi scaricare i progetti di cui abbiamo condiviso i link github sopra e modificare solo le \<font color="#2166ae">appid\</font> e \<font color="#2166ae">clientkey\</font> parti secondo le tue esigenze 1 salva e elenca gli oggetti correlati dei libri in questo passaggio vedremo come salvare e elencare i \<font color="#2166ae">generi\</font> , \<font color="#2166ae">editori\</font> e \<font color="#2166ae">autori\</font> classi relative alla \<font color="#2166ae">libro\</font> classe 1 1 salva e elenca i generi possiamo registrare un \<font color="#2166ae">genere\</font> utilizzando il seguente frammento 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 } possiamo registrare un \<font color="#2166ae">genere\</font> utilizzando il seguente frammento 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 salva e elenca gli editori possiamo registrare un \<font color="#2166ae">editore\</font> utilizzando il seguente frammento 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 } possiamo registrare un \<font color="#2166ae">editore\</font> utilizzando il seguente frammento 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 salva e lista autori possiamo registrare un \<font color="#2166ae">autore\</font> utilizzando il seguente frammento 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 } possiamo registrare un \<font color="#2166ae">autore\</font> utilizzando il seguente frammento 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 } in questa parte, utilizziamo una classe modello chiamata \<font color="#2166ae">parseobjectmodel\</font> in questa classe modello, abbiamo una \<font color="#2166ae">parseobject\</font> variabile per poter leggere i dati, e la \<font color="#2166ae">ischecked\</font> variabile, che utilizzeremo per salvare il libro nel passaggio successivo saremo in grado di recuperare facilmente gli oggetti selezionati con la \<font color="#2166ae">ischecked\</font> variabile ecco il nostro \<font color="#2166ae">parseobjectmodel\</font> modello 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 salva un oggetto libro e le sue relazioni 2 1 salva un oggetto libro con relazione 1\ n questa funzione creerà un nuovo \<font color="#2166ae">libro\</font> nel database di back4app con relazioni 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 salva un oggetto libro con relazione n\ n questa funzione creerà un nuovo \<font color="#2166ae">libro\</font> nel database di back4app con relazioni n\ n per la \<font color="#2166ae">autore\</font> relazione, troviamo gli autori selezionati nell'adapter del \<font color="#2166ae">authorrecyclerview\</font> e li salviamo come \<font color="#2166ae">relazione 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 interrogare i dettagli del libro con relazioni con queste funzioni, elencheremo i nostri \<font color="#2166ae">libri\</font> in base ai loro \<font color="#2166ae">editori\</font> prima, lanciamo una query alla classe publisher 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 } e poi facciamo una query per elencare i \<font color="#2166ae">libri\</font> a cui ogni \<font color="#2166ae">editore\</font> è correlato 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 } ora, quando clicchiamo su qualsiasi \<font color="#2166ae">libro\</font> oggetto, inviamo l'id dell'oggetto di questo \<font color="#2166ae">libro\</font> con un'intenzione alla pagina che mostrerà i dettagli di quel \<font color="#2166ae">libro\</font> e otteniamo tutti i dettagli del \<font color="#2166ae">libro \</font> dal database utilizzando questo id dell'oggetto su quella pagina 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 } è fatto! a questo punto, abbiamo imparato \<font color="#2166ae">relazioni parse\</font> su \<font color="#2166ae">android\</font>