1:1 Relationship
9 นาที
ความสัมพันธ์แบบหนึ่งต่อหนึ่ง บทนำ ที่แกนกลางของหลายๆ แบ็คเอนด์ คุณจะพบความสามารถในการจัดเก็บข้อมูล โดยการใช้ parse คุณสามารถจัดเก็บวัตถุข้อมูลที่สร้างความสัมพันธ์ระหว่างกัน ความสัมพันธ์ของข้อมูลจะทำให้มาตรฐานว่าแต่ละวัตถุข้อมูลมีความสัมพันธ์หรือเชื่อมโยงกับวัตถุอื่นอย่างไร ซึ่งสามารถให้พลังเพิ่มเติมเมื่อคุณสร้างและรันคำค้นหาที่ซับซ้อน มีประเภทความสัมพันธ์หลักสามประเภท \<font color="#2166ae">หนึ่งต่อหลาย\</font> , ซึ่งวัตถุหนึ่งสามารถเชื่อมโยงกับวัตถุอื่นๆ ได้หลายวัตถุ; \<font color="#2166ae">หนึ่งต่อหนึ่ง\</font> , สร้างความสัมพันธ์โดยตรงระหว่างสองวัตถุและเฉพาะพวกเขาเท่านั้น; \<font color="#2166ae">หลายต่อหลาย\</font> , ซึ่งสามารถสร้างความสัมพันธ์ที่ซับซ้อนมากมายระหว่างวัตถุหลายๆ ตัว ในคู่มือนี้ เราจะมุ่งเน้นไปที่ความสัมพันธ์แบบหนึ่งต่อหนึ่ง ความสัมพันธ์เหล่านี้เป็นเรื่องปกติในแอปพลิเคชันที่เกี่ยวข้องกับข้อมูลที่ละเอียดอ่อนและการจัดการผู้ใช้ ซึ่งต้องการฟิลด์ที่ไม่ซ้ำกันที่ต้องบังคับ เช่น หมายเลขประจำตัวและหมายเลขโทรศัพท์ แบ็กเอนด์การจัดเก็บข้อมูลมักจะต้องการการประกาศความสัมพันธ์เหล่านี้อย่างชัดเจน และ parse ไม่มีวิธีแก้ปัญหาอัตโนมัติสำหรับการบรรลุความสัมพันธ์ดังกล่าว อย่างไรก็ตาม มีวิธีการในการดำเนินการความสัมพันธ์ 1 1 ใน parse โดยการใช้ \<font color="#2166ae">parse cloud\</font> ฟังก์ชันบนเซิร์ฟเวอร์ของคุณ ซึ่งบังคับให้ความสัมพันธ์ในตารางยังคงไม่ซ้ำกันก่อนที่จะบันทึกข้อมูล สิ่งนี้ทำได้โดยการสร้าง \<font color="#2166ae">beforesave\</font> ฟังก์ชันในทั้งสองคลาสที่เกี่ยวข้องและป้องกันไม่ให้บันทึกหากคลาสพ่อมีอินสแตนซ์หนึ่งในคลาสลูกอยู่แล้ว และในทางกลับกัน คุณยังสามารถจัดการกรณีเหล่านี้ในโค้ด parse ของแอปพลิเคชันของคุณ โดยการสอบถามเซิร์ฟเวอร์ก่อนที่จะบันทึกและรับประกันความสัมพันธ์ดังกล่าว นี่จะเป็นวิธีที่แสดงในคู่มือนี้ แต่โปรดทราบว่าการใช้ฟังก์ชันคลาวด์นั้นสะอาดและแนะนำมากกว่า ในคู่มือนี้ คุณจะดำเนินการสร้างแอปพลิเคชันการลงทะเบียนหนังสือ react native ที่มีความสัมพันธ์ข้อมูลหลักสามประเภท คุณจะได้เรียนรู้วิธีการสร้างและสอบถามความสัมพันธ์ข้อมูลแบบหนึ่งต่อหนึ่งโดยใช้ back4app และ react native ในทุกช่วงเวลา คุณสามารถเข้าถึงโครงการนี้ได้ผ่านทางที่เก็บ github ของเราเพื่อตรวจสอบสไตล์และโค้ดที่สมบูรณ์ ที่เก็บตัวอย่าง javascript https //github com/templates back4app/react native js associations ที่เก็บตัวอย่าง typescript https //github com/templates back4app/react native ts associations ข้อกำหนดเบื้องต้น ในการทำตามบทเรียนนี้ คุณจะต้องมี แอป react native ที่สร้างและเชื่อมต่อกับ back4app https //www back4app com/docs/react native/parse sdk/react native sdk หากคุณต้องการทดสอบ/ใช้เลย์เอาต์หน้าจอที่จัดเตรียมโดยคู่มือนี้ คุณควรติดตั้ง \<font color="#2166ae">react native paper\</font> ไลบรารี https //github com/callstack/react native paper เป้าหมาย เพื่อดำเนินการและแสดงความสัมพันธ์ระหว่างฐานข้อมูลแบบหนึ่งต่อหนึ่งใน react native โดยใช้ parse ในสถานการณ์ที่สมจริง 1 การทำความเข้าใจคลาส book เนื่องจากในคู่มือนี้เราจะใช้ตัวอย่างแอปพลิเคชันการลงทะเบียนหนังสือ คุณต้องเข้าใจก่อนว่าความสัมพันธ์ของวัตถุถูกจัดเรียงอย่างไรในฐานข้อมูลนี้ คลาสวัตถุหลักที่คุณจะใช้คือ \<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">isdb\</font> หมายเลขระบุ isdb ของหนังสือ ความสัมพันธ์แบบหนึ่งต่อหนึ่งกับ \<font color="#2166ae">หนังสือ\</font> , เนื่องจากหมายเลขนี้มีเอกลักษณ์สำหรับแต่ละเล่ม นี่คือการแสดงภาพของตารางฐานข้อมูลเหล่านี้ เพื่อความเรียบง่าย เราจะสมมติว่าแต่ละคลาสวัตถุมีเพียงประเภทสตริง \<font color="#2166ae">ชื่อ\</font> แอตทริบิวต์ ( \<font color="#2166ae">ชื่อเรื่อง\</font> สำหรับ \<font color="#2166ae">หนังสือ\</font> ) นอกเหนือจากแอตทริบิวต์เชิงสัมพันธ์เพิ่มเติมใดๆ 2 การสร้างความสัมพันธ์แบบหนึ่งต่อหลาย ก่อนที่จะไปยังขั้นตอนนี้ เราขอแนะนำให้คุณโคลนและรันแอปตัวอย่าง react native library ( ที่เก็บตัวอย่าง javascript https //github com/templates back4app/react native js associations , ที่เก็บตัวอย่าง typescript https //github com/templates back4app/react native ts associations ) แอปพลิเคชันนี้มีสองหน้าหลัก หนึ่งหน้าที่รับผิดชอบในการแสดงรายการหนังสือที่ลงทะเบียนและอีกหน้าหนึ่งสำหรับการสร้างหนังสือใหม่ ในแบบฟอร์มการลงทะเบียนหนังสือ จะมีลิงก์โดยตรงไปยังวัตถุที่เกี่ยวข้องอื่นๆ และมี \<font color="#2166ae">textinput\</font> ฟิลด์ที่กำหนดให้กับค่าของ isbd ของหนังสือ ซึ่งจะใช้ในการสร้างความสัมพันธ์แบบหนึ่งต่อหนึ่งของคุณ มาดูวิธีการสร้างหนังสือที่ถูกเรียกเมื่อส่งแบบฟอร์มนี้ javascript 1 const createbook = async function () { 2 try { 3 // these values come from state variables linked to 4 // the screen form fields, retrieving the user choices 5 // as a complete parse object, when applicable; 6 const booktitlevalue = booktitle; 7 const bookisbdvalue = bookisbd; 8 // for example, bookpublisher holds the value from 9 // radiobutton group field with its options being every 10 // publisher parse object instance saved on server, which is 11 // queried on screen load via useeffect 12 const bookpublisherobject = bookpublisher; 13 const bookgenreobject = bookgenre; 14 // bookauthors can be an array of parse objects, since the book 15 // may have more than one author 16 const bookauthorsobjects = bookauthors; 17	 18 // creates a new parse object instance 19 let book = new parse object('book'); 20	 21 // set data to parse object 22 // simple title field 23 book set('title', booktitlevalue); 24	 25 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 26 let isbdquery = new parse query('isbd'); 27 isbdquery equalto('name', bookisbdvalue); 28 let isbdqueryresult = await isbdquery first(); 29 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 30 // if first returns a valid object instance, it means that there 31 // is at least one instance of isbd with the informed value 32 alert alert( 33 'error!', 34 'there is already an isbd instance with this value!', 35 ); 36 return false; 37 } else { 38 // create a new isbd object instance to create a one to one relation on saving 39 let isbd = new parse object('isbd'); 40 isbd set('name', bookisbdvalue); 41 isbd = await isbd save(); 42 // set the new object to the new book object isbd field 43 book set('isbd', isbd); 44 } 45	 46 // one to many relations can be set in two ways 47 // add direct object to field (parse will convert to pointer on save) 48 book set('publisher', bookpublisherobject); 49 // or add pointer to field 50 book set('genre', bookgenreobject topointer()); 51	 52 // many to many relation 53 // create a new relation so data can be added 54 let authorsrelation = book relation('authors'); 55 // bookauthorsobjects is an array of parse objects, 56 // you can add to relation by adding the whole array or object by object 57 authorsrelation add(bookauthorsobjects); 58	 59 // after setting the values, save it on the server 60 try { 61 await book save(); 62 // success 63 alert alert('success!'); 64 navigation goback(); 65 return true; 66 } catch (error) { 67 // error can be caused by lack of internet connection 68 alert alert('error!', error message); 69 return false; 70 } 71 } catch (error) { 72 // error can be caused by lack of value selection 73 alert alert( 74 'error!', 75 'make sure to select valid choices in publisher, genre and author fields!', 76 ); 77 return false; 78 } 79 }; todolist tsx 1 const createbook = async function () promise\<boolean> { 2 try { 3 // these values come from state variables linked to 4 // the screen form fields, retrieving the user choices 5 // as a complete parse object, when applicable; 6 const booktitlevalue string = booktitle; 7 const bookisbdvalue string = bookisbd; 8 // for example, bookpublisher holds the value from 9 // radiobutton group field with its options being every 10 // publisher parse object instance saved on server, which is 11 // queried on screen load via useeffect 12 const bookpublisherobject parse object = bookpublisher; 13 const bookgenreobject parse object = bookgenre; 14 // bookauthors can be an array of parse objects, since the book 15 // may have more than one author 16 const bookauthorsobjects \[parse object] = bookauthors; 17	 18 // creates a new parse object instance 19 let book parse object = new parse object('book'); 20	 21 // set data to parse object 22 // simple title field 23 book set('title', booktitlevalue); 24	 25 // 1 1 relation, need to check for uniqueness of value before creating a new isbd object 26 let isbdquery parse query = new parse query('isbd'); 27 isbdquery equalto('name', bookisbdvalue); 28 let isbdqueryresult parse object = await isbdquery first(); 29 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 30 // if first returns a valid object instance, it means that there 31 // is at least one instance of isbd with the informed value 32 alert alert( 33 'error!', 34 'there is already an isbd instance with this value!', 35 ); 36 return false; 37 } else { 38 // create a new isbd object instance to create a one to one relation on saving 39 let isbd parse object = new parse object('isbd'); 40 isbd set('name', bookisbdvalue); 41 isbd = await isbd save(); 42 // set the new object to the new book object isbd field 43 book set('isbd', isbd); 44 } 45	 46 // one to many relations can be set in two ways 47 // add direct object to field (parse will convert to pointer on save) 48 book set('publisher', bookpublisherobject); 49 // or add pointer to field 50 book set('genre', bookgenreobject topointer()); 51	 52 // many to many relation 53 // create a new relation so data can be added 54 let authorsrelation = book relation('authors'); 55 // bookauthorsobjects is an array of parse objects, 56 // you can add to relation by adding the whole array or object by object 57 authorsrelation add(bookauthorsobjects); 58	 59 // after setting the values, save it on the server 60 try { 61 await book save(); 62 // success 63 alert alert('success!'); 64 navigation goback(); 65 return true; 66 } catch (error) { 67 // error can be caused by lack of internet connection 68 alert alert('error!', error message); 69 return false; 70 } 71 } catch (error) { 72 // error can be caused by lack of value selection 73 alert alert( 74 'error!', 75 'make sure to select valid choices in publisher, genre and author fields!', 76 ); 77 return false; 78 } 79 }; ดูว่า \<font color="#2166ae">bookisbdvalue\</font> ถูกตั้งค่าเป็นหนังสือใหม่ \<font color="#2166ae">parse object\</font> ตัวอย่าง การสร้างและบันทึกความสัมพันธ์แบบหนึ่งต่อหนึ่งและแบบหนึ่งต่อหลายใน parse เป็นกระบวนการที่คล้ายกัน ซึ่งคุณจะส่ง \<font color="#2166ae">parse object\</font> ตัวอย่างเป็นอาร์กิวเมนต์โดยใช้ \<font color="#2166ae">parse object set\</font> วิธีการ ซึ่งมีสองอาร์กิวเมนต์ ชื่อฟิลด์และค่าที่จะตั้ง จุดที่ต้องระวังคือ ก่อนที่จะบันทึก คุณต้องบังคับให้ไม่มี \<font color="#2166ae">isbd\</font> วัตถุที่มีค่า id สตริง isbd ที่แจ้งในฐานข้อมูลของคุณ และไม่มี \<font color="#2166ae">book\</font> วัตถุที่เกี่ยวข้องกับมันอยู่แล้ว ส่วนที่สองจะเป็นจริงเสมอในกรณีนี้ เนื่องจากคุณกำลังสร้าง \<font color="#2166ae">book\</font> วัตถุใหม่ทุกครั้ง การบังคับให้ \<font color="#2166ae">isbd\</font> มีเอกลักษณ์สามารถทำได้โดยการใช้คำค้นที่เน้นดังต่อไปนี้ javascript 1 let isbdquery = new parse query('isbd'); 2 isbdquery equalto('name', bookisbdvalue); 3 let isbdqueryresult = await isbdquery first(); 4 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 5 // if first returns a valid object instance, it means that there 6 // is at least one instance of isbd with the informed value 7 alert alert( 8 'error!', 9 'there is already an isbd instance with this value!', 10 ); 11 return false; 12 } todolist tsx 1 let isbdquery parse query = new parse query('isbd'); 2 isbdquery equalto('name', bookisbdvalue); 3 let isbdqueryresult parse object = await isbdquery first(); 4 if (isbdqueryresult !== null && isbdqueryresult !== undefined) { 5 // if first returns a valid object instance, it means that there 6 // is at least one instance of isbd with the informed value 7 alert alert( 8 'error!', 9 'there is already an isbd instance with this value!', 10 ); 11 return false; 12 } หลังจากที่คุณบันทึกวัตถุของคุณสำเร็จแล้ว parse จะสร้างคอลัมน์ประเภทข้อมูลพอยน์เตอร์และลิงก์ตรงบนแดชบอร์ดของคุณเพื่อการเข้าถึงอย่างรวดเร็วภายใต้พื้นผิว 3 การสอบถามความสัมพันธ์แบบหนึ่งต่อหนึ่ง การสอบถามวัตถุที่เกี่ยวข้องแบบหนึ่งต่อหนึ่งนั้นค่อนข้างตรงไปตรงมา เนื่องจากส่วนใหญ่จะถูกจัดการโดย parse ดูฟังก์ชันการสอบถามในหน้าจอรายการทะเบียนหนังสือ javascript 1 const querybooks = async function () { 2 // these values come from state variables linked to 3 // the screen query radiobutton group fields, with its options being every 4 // parse object instance saved on server from the referred class, which is 5 // queried on screen load via useeffect; these variables retrievie the user choices 6 // as a complete parse object; 7 const querypublishervalue = querypublisher; 8 const querygenrevalue = querygenre; 9 const queryauthorvalue = queryauthor; 10 const queryisbdvalue = queryisbd; 11	 12 // reading parse objects is done by using parse query 13 const parsequery = new parse query('book'); 14	 15 // one to many queries 16 if (querypublishervalue !== '') { 17 parsequery equalto('publisher', querypublishervalue); 18 } 19 if (querygenrevalue !== '') { 20 parsequery equalto('genre', querygenrevalue); 21 } 22	 23 // one to one query 24 if (queryisbdvalue !== '') { 25 parsequery equalto('isbd', queryisbdvalue); 26 } 27	 28 // many to many query 29 // in this case, we need to retrieve books related to the chosen author 30 if (queryauthorvalue !== '') { 31 parsequery equalto('authors', queryauthorvalue); 32 } 33	 34 try { 35 let books = await parsequery find(); 36 // many to many objects retrieval 37 // in this example we need to get every related author parse object 38 // and add it to our query result objects 39 for (let book of books) { 40 // this query is done by creating a relation and querying it 41 let bookauthorsrelation = book relation('authors'); 42 book authorsobjects = await bookauthorsrelation query() find(); 43 } 44 setqueriedbooks(books); 45 return true; 46 } catch (error) { 47 // error can be caused by lack of internet connection 48 alert alert('error!', error message); 49 return false; 50 } 51 }; todolist tsx 1 const querybooks = async function () promise\<boolean> { 2 // these values come from state variables linked to 3 // the screen query radiobutton group fields, with its options being every 4 // parse object instance saved on server from the referred class, which is 5 // queried on screen load via useeffect; these variables retrievie the user choices 6 // as a complete parse object; 7 const querypublishervalue parse object = querypublisher; 8 const querygenrevalue parse object = querygenre; 9 const queryauthorvalue parse object = queryauthor; 10 const queryisbdvalue parse object = queryisbd; 11	 12 // reading parse objects is done by using parse query 13 const parsequery parse query = new parse query('book'); 14	 15 // one to many queries 16 if (querypublishervalue !== '') { 17 parsequery equalto('publisher', querypublishervalue); 18 } 19 if (querygenrevalue !== '') { 20 parsequery equalto('genre', querygenrevalue); 21 } 22	 23 // one to one query 24 if (queryisbdvalue !== '') { 25 parsequery equalto('isbd', queryisbdvalue); 26 } 27	 28 // many to many query 29 // in this case, we need to retrieve books related to the chosen author 30 if (queryauthorvalue !== '') { 31 parsequery equalto('authors', queryauthorvalue); 32 } 33	 34 try { 35 let books \[parse object] = await parsequery find(); 36 // many to many objects retrieval 37 // in this example we need to get every related author parse object 38 // and add it to our query result objects 39 for (let book of books) { 40 // this query is done by creating a relation and querying it 41 let bookauthorsrelation = book relation('authors'); 42 book authorsobjects = await bookauthorsrelation query() find(); 43 } 44 setqueriedbooks(books); 45 return true; 46 } catch (error) { 47 // error can be caused by lack of internet connection 48 alert alert('error!', error message); 49 return false; 50 } 51 }; ในกรณีนี้ เพื่อค้นหาหนังสือใด ๆ ที่เกี่ยวข้องกับ isbd เฉพาะ คุณเพียงแค่ต้องใช้ \<font color="#2166ae">parse query equalto\</font> วิธีการโดยส่ง \<font color="#2166ae">parse object\</font> ตัวอย่างเป็นพารามิเตอร์ หลังจากการค้นหา parse จะเก็บตัวอย่างที่สมบูรณ์ของฟิลด์ความสัมพันธ์แบบหนึ่งต่อหนึ่งในวัตถุที่ได้ผลลัพธ์ เพื่อดึงข้อมูลและแสดงข้อมูลจากตัวอย่างวัตถุเหล่านี้ คุณสามารถเชื่อมโยง \<font color="#2166ae">parse object get\</font> วิธีการแบบนี้ \<font color="#2166ae">bookparseobject get(('isbd') get('name')\</font> นี่คือวิธีที่หน้ารายการดูเหมือนเมื่อใช้ getters เหล่านี้เพื่อดึงชื่อ isbd จากรายการ บทสรุป ในตอนท้ายของคู่มือนี้ คุณได้เรียนรู้วิธีการสร้างและค้นหาความสัมพันธ์แบบหนึ่งต่อหนึ่งใน parse บน react native ในคู่มือต่อไป เราจะแสดงให้คุณเห็นวิธีการลงทะเบียนผู้ใช้