การจัดการความสัมพันธ์ของข้อมูลใน Parse สำหรับ Android
19 นาที
ความสัมพันธ์บน android บทนำ ด้วย parse คุณสามารถจัดเก็บวัตถุข้อมูลที่สร้างความสัมพันธ์ระหว่างกัน เพื่อจำลองพฤติกรรมนี้ วัตถุใด ๆ \<font color="#2166ae">parseobject\</font> สามารถใช้เป็นค่าใน \<font color="#2166ae">parseobject\</font> ภายในเฟรมเวิร์ก parse จะจัดเก็บวัตถุที่ถูกอ้างอิงไว้ในที่เดียวเพื่อรักษาความสอดคล้อง ซึ่งจะช่วยให้คุณมีพลังเพิ่มเติมเมื่อสร้างและรันคำค้นหาที่ซับซ้อน มีประเภทความสัมพันธ์หลักสามประเภท \<font color="#2166ae">หนึ่งต่อหนึ่ง\</font> , สร้างความสัมพันธ์โดยตรงระหว่างวัตถุสองตัวและเฉพาะพวกเขา; \<font color="#2166ae">หนึ่งต่อหลาย\</font> , ซึ่งวัตถุหนึ่งสามารถเกี่ยวข้องกับวัตถุอื่น ๆ ได้หลายตัว; \<font color="#2166ae">หลายต่อหลาย\</font> , ซึ่งสามารถสร้างความสัมพันธ์ที่ซับซ้อนมากมายระหว่างวัตถุหลายตัว มีสองวิธีในการสร้าง \<font color="#2166ae">ความสัมพันธ์แบบหนึ่งต่อหลาย\</font> ใน parse วิธีแรกคือการใช้ \<font color="#2166ae">พอยเตอร์\</font> ใน \<font color="#2166ae">คลาสลูก\</font> ซึ่งเป็นวิธีที่เร็วที่สุดในด้านการสร้างและเวลาค้นหา วิธีที่สองคือการใช้ \<font color="#2166ae">อาร์เรย์\</font> ของ \<font color="#2166ae">พอยเตอร์\</font> ในคลาสพ่อแม่ซึ่งอาจทำให้เวลาค้นหาช้า ขึ้นอยู่กับขนาดของมัน เนื่องจากปัญหาด้านประสิทธิภาพนี้ เราจะใช้เฉพาะตัวอย่างพอยเตอร์เท่านั้น มีสามวิธีในการสร้าง \<font color="#2166ae">ความสัมพันธ์แบบหลายต่อหลาย\</font> ใน parse วิธีแรกคือการใช้ parse \<font color="#2166ae">ความสัมพันธ์\</font> , ซึ่งเป็นวิธีที่เร็วที่สุดในด้านการสร้างและเวลาค้นหา เราจะใช้สิ่งนี้ในคู่มือนี้ วิธีที่สองคือการใช้ \<font color="#2166ae">อาร์เรย์\</font> ของ \<font color="#2166ae">พอยเตอร์\</font> ซึ่งอาจทำให้เวลาค้นหาช้า ขึ้นอยู่กับขนาดของมัน วิธีที่สามคือการใช้ \<font color="#2166ae">jointable\</font> ซึ่งมีแนวคิดมาจากฐานข้อมูลคลาสสิก เมื่อมีความสัมพันธ์แบบหลายต่อหลาย เราจะรวมทุก \<font color="#2166ae">objectid\</font> หรือ \<font color="#2166ae">พอยเตอร์\</font> จากทั้งสองด้านเข้าด้วยกันเพื่อสร้างตารางแยกใหม่ซึ่งความสัมพันธ์จะถูกติดตาม บทเรียนนี้ใช้แอปพื้นฐานที่สร้างขึ้นใน android studio 4 1 1 พร้อมกับ \<font color="#2166ae">buildtoolsversion=30 0 2\</font> , \<font color="#2166ae">compile sdk version = 30 0 2\</font> และ \<font color="#2166ae">targetsdkversion 30\</font> ในทุกเวลา คุณสามารถเข้าถึงโปรเจกต์ android ที่สร้างขึ้นด้วยบทเรียนนี้ได้ที่ที่เก็บ github ของเรา ที่เก็บตัวอย่าง kotlin https //github com/templates back4app/android parse sdk kotlin ที่เก็บตัวอย่าง java https //github com/templates back4app/android parse sdk java เป้าหมาย เป้าหมายของเราคือการเข้าใจความสัมพันธ์ของ parse โดยการสร้างแอปหนังสือที่ใช้งานได้จริง นี่คือภาพรวมสิ่งที่เราจะทำให้สำเร็จ ข้อกำหนดเบื้องต้น ในการทำตามบทเรียนนี้ เราต้องการ android studio https //developer android com/studio/index html แอปที่สร้างขึ้นบน back4app หมายเหตุ ติดตาม บทเรียนการสร้าง parse app ใหม่ https //www back4app com/docs/get started/new parse app เพื่อเรียนรู้วิธีการสร้าง parse app บน back4app แอป android ที่เชื่อมต่อกับ back4app หมายเหตุ ติดตาม บทเรียนการติดตั้ง parse sdk https //www back4app com/docs/android/parse android sdk เพื่อสร้างโปรเจกต์ android studio ที่เชื่อมต่อกับ back4app อุปกรณ์ (หรือ อุปกรณ์เสมือน https //developer android com/studio/run/managing avds html ) ที่รัน android 4 1 (jelly bean) หรือใหม่กว่า การทำความเข้าใจแอปหนังสือ คลาสวัตถุหลักที่คุณจะใช้คือ \<font color="#2166ae">หนังสือ\</font> คลาส ซึ่งเก็บข้อมูลหนังสือแต่ละรายการในระบบการลงทะเบียน นอกจากนี้ยังมีคลาสวัตถุอีกสามคลาสดังนี้ \<font color="#2166ae">ผู้จัดพิมพ์\</font> ชื่อผู้จัดพิมพ์หนังสือ, \<font color="#2166ae">หนึ่งต่อหลาย\</font> ความสัมพันธ์กับ \<font color="#2166ae">หนังสือ\</font> \<font color="#2166ae">ประเภท\</font> ประเภทหนังสือ, \<font color="#2166ae">หนึ่งต่อหลาย\</font> ความสัมพันธ์กับ \<font color="#2166ae">หนังสือ\</font> โปรดทราบว่าสำหรับตัวอย่างนี้เราจะพิจารณาว่าหนังสือสามารถมีประเภทเดียวเท่านั้น; \<font color="#2166ae">ผู้เขียน\</font> ผู้เขียนหนังสือ, \<font color="#2166ae">หลายต่อหลาย\</font> ความสัมพันธ์กับ \<font color="#2166ae">หนังสือ\</font> , เนื่องจากหนังสือสามารถมีผู้เขียนได้มากกว่าหนึ่งคนและผู้เขียนสามารถมีหนังสือได้มากกว่าหนึ่งเล่มเช่นกัน; การแสดงภาพของโมเดลข้อมูลเหล่านี้ เริ่มกันเถอะ! ก่อนที่จะดำเนินการต่อ เราต้องเชื่อมต่อ \<font color="#2166ae">back4app\</font> กับแอปพลิเคชันของเรา คุณควรบันทึก \<font color="#2166ae">appid\</font> และ \<font color="#2166ae">clientkey\</font> จาก \<font color="#2166ae">back4app\</font> ไปยัง \<font color="#2166ae">string xml\</font> ไฟล์และจากนั้นเริ่ม \<font color="#2166ae">parse\</font> ใน \<font color="#2166ae">app java\</font> หรือ \<font color="#2166ae">app kt\</font> ไฟล์ ติดตาม คู่มือการสร้างแอป parse ใหม่ https //www back4app com/docs/android/parse android sdk หากคุณไม่รู้ว่าจะเริ่ม \<font color="#2166ae">parse\</font> ในแอปของคุณอย่างไร หรือคุณสามารถดาวน์โหลดโปรเจกต์ที่เราแชร์ลิงก์ github ข้างต้นและแก้ไขเฉพาะ \<font color="#2166ae">appid\</font> และ \<font color="#2166ae">clientkey\</font> ตามที่คุณต้องการ 1 บันทึกและแสดงรายการวัตถุที่เกี่ยวข้องกับหนังสือ ในขั้นตอนนี้เราจะดูวิธีการบันทึกและแสดงรายการ \<font color="#2166ae">ประเภท\</font> , \<font color="#2166ae">ผู้จัดพิมพ์\</font> และ \<font color="#2166ae">ผู้เขียน\</font> ที่เกี่ยวข้องกับ \<font color="#2166ae">หนังสือ\</font> คลาส 1 1 บันทึกและแสดงรายการประเภท เราสามารถลงทะเบียน \<font color="#2166ae">ประเภท\</font> โดยใช้โค้ดต่อไปนี้ 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 } เราสามารถลงทะเบียน \<font color="#2166ae">ประเภท\</font> โดยใช้โค้ดต่อไปนี้ 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 บันทึกและแสดงรายการผู้เผยแพร่ เราสามารถลงทะเบียน \<font color="#2166ae">ผู้เผยแพร่\</font> โดยใช้โค้ดต่อไปนี้ 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 } เราสามารถลงทะเบียน \<font color="#2166ae">ผู้เผยแพร่\</font> โดยใช้โค้ดต่อไปนี้ 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 บันทึกและแสดงรายชื่อผู้เขียน เราสามารถลงทะเบียน \<font color="#2166ae">ผู้เขียน\</font> โดยใช้โค้ดตัวอย่างต่อไปนี้ 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 } เราสามารถลงทะเบียน \<font color="#2166ae">ผู้เขียน\</font> โดยใช้โค้ดตัวอย่างต่อไปนี้ 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 } ในส่วนนี้ เราใช้คลาสโมเดลที่ชื่อว่า \<font color="#2166ae">parseobjectmodel\</font> ในคลาสโมเดลนี้ เรามีตัวแปร \<font color="#2166ae">parseobject\</font> เพื่อที่จะสามารถอ่านข้อมูลได้ และตัวแปร \<font color="#2166ae">ischecked\</font> ซึ่งเราจะใช้เพื่อบันทึกหนังสือในขั้นตอนถัดไป เราจะสามารถดึงวัตถุที่เลือกได้อย่างง่ายดายด้วยตัวแปร \<font color="#2166ae">ischecked\</font> นี่คือโมเดล \<font color="#2166ae">parseobjectmodel\</font> ของเรา 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 ฟังก์ชันนี้จะสร้าง \<font color="#2166ae">หนังสือ\</font> ใหม่ในฐานข้อมูล 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 ฟังก์ชันนี้จะสร้าง \<font color="#2166ae">หนังสือ\</font> ใหม่ในฐานข้อมูล back4app โดยมีความสัมพันธ์แบบ n\ n สำหรับ \<font color="#2166ae">ผู้เขียน\</font> เราจะค้นหาผู้เขียนที่เลือกในตัวปรับแต่งของ \<font color="#2166ae">authorrecyclerview\</font> และบันทึกพวกเขาเป็น \<font color="#2166ae">ความสัมพันธ์ 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 สอบถามรายละเอียดหนังสือพร้อมความสัมพันธ์ ด้วยฟังก์ชันเหล่านี้ เราจะทำการจัดรายการ \<font color="#2166ae">หนังสือ\</font> ตาม \<font color="#2166ae">ผู้จัดพิมพ์\</font> ก่อนอื่น เราจะส่งคำค้นไปยังคลาส 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 } จากนั้นเราจะทำการสอบถามเพื่อแสดงรายการ \<font color="#2166ae">หนังสือ\</font> ที่แต่ละ \<font color="#2166ae">ผู้จัดพิมพ์\</font> เกี่ยวข้องกับ 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 } ตอนนี้เมื่อเราคลิกที่ \<font color="#2166ae">หนังสือ\</font> ใด ๆ เราจะส่ง object id ของ \<font color="#2166ae">หนังสือ\</font> นี้ไปยังหน้าที่จะแสดงรายละเอียดของ \<font color="#2166ae">หนังสือ\</font> และเราจะได้รับรายละเอียดทั้งหมดของ \<font color="#2166ae">หนังสือ \</font> จากฐานข้อมูลโดยใช้ object id นี้ในหน้านั้น 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 } เสร็จแล้ว! ในจุดนี้ เราได้เรียนรู้ \<font color="#2166ae">ความสัมพันธ์ของ parse\</font> บน \<font color="#2166ae">android\</font>