1. การทำแผนที่คอลเลกชัน
1. บทนำคอลเลกชัน
การทำแผนที่คอลเลกชันยังเป็นการทำแผนที่ขั้นพื้นฐาน แต่จะไม่ถูกใช้บ่อยในระหว่างกระบวนการพัฒนาดังนั้นจึงไม่จำเป็นต้องมีความเข้าใจอย่างลึกซึ้ง คุณต้องเข้าใจวิธีการใช้งานขั้นพื้นฐานเท่านั้น เพียงแค่สามารถสอบถามวิธีแก้ปัญหาเมื่อคุณพบปัญหาดังกล่าวในระหว่างกระบวนการพัฒนา การแมปชุดที่สอดคล้องกันในความเป็นจริงมันหมายถึงการแมปชุดใน Java ไปยังตารางที่สอดคล้องกัน มันคือการทำแผนที่ของวัตถุคอลเลกชัน มีชุดสี่ประเภทใน Java คือชุดแผนที่แผนที่รายการและอาร์เรย์สามัญ มีความแตกต่างอย่างมากระหว่างพวกเขา:
(1) ตั้งค่าไม่ควรมีวัตถุที่ซ้ำกันวัตถุนั้นไม่เป็นระเบียบ
(2) รายการสามารถสั่งซื้อได้ด้วยวัตถุซ้ำ
(3) แผนที่จะปรากฏเป็นคู่ของค่าคีย์
(4) สามารถทำซ้ำอาร์เรย์และมีคำสั่งระหว่างวัตถุ
ความแตกต่างระหว่างพวกเขากำหนดว่าการรวบรวมใดที่ใช้ในระหว่างการพัฒนา โดยปกติแล้วชุดจะใช้ในระหว่างการพัฒนา วัตถุภายในไม่จำเป็นและวัตถุภายในสามารถรับได้โดยใช้ตัววนซ้ำ หากชุดเหล่านี้ต้องการแมปกับโมเดลเชิงสัมพันธ์ที่สอดคล้องกันคุณต้องใช้แท็กการแมปที่จัดทำโดย Hibernate, <et>, <list>, <map>, และ <rray>
2. การทำแผนที่บทนำ
ดำเนินการต่อเพื่อหารือเกี่ยวกับรูปแบบความสัมพันธ์ของการทำแผนที่ชุด Set Mapping หมายถึงวัตถุที่สอดคล้องกับการรวบรวมวัตถุอื่น เมื่อบันทึก Hibernate จะบันทึกชุดข้อมูลไปยังตารางที่สอดคล้องกันและบันทึกข้อมูลไปยังตารางข้อมูลตาม ID ที่จัดสรร หากตารางใหม่ถูกกำหนดให้กับชุดแยกต่างหาก ID จะถูกกำหนดให้กับ ID ของตารางที่ตั้งไว้และตารางความสัมพันธ์ที่สอดคล้องกันมีดังนี้:
3. ไฟล์คลาส
วิธีการทำแผนที่ตั้งค่าผ่านรหัสและเราจะวิเคราะห์โดยละเอียดต่อไป ที่นี่เราปิดผนึกคอลเลกชันทั้งหมดในชั้นเรียน เราเรียกคลาสนี้ collectionmapping.java ดังนั้นรหัสภายในที่สอดคล้องกันของมันมีดังนี้:
แพ็คเกจ com.hibernate; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า java.util.set; @suppresswarnings ("rawtypes") การรวบรวมคลาสสาธารณะ {// id id private int id; สาธารณะ int getId () {return id; } โมฆะสาธารณะ setId (int id) {this.id = id; } // ชื่อชื่อสตริงส่วนตัว; สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; } // SET COLLECTION SET SET Private SetValues; Public Set GetSetValues () {return setValues; } โมฆะสาธารณะ setSetValues (set setValues) {this.setValues = setValues; } // รายการรวบรวมรายการส่วนตัว ListValues; รายการสาธารณะ getListValues () {return listValues; } โมฆะสาธารณะ setlistValues (รายการ ListValues) {this.listValues = ListValues; } // Array Collection String ส่วนตัว [] ArrayValues; สตริงสาธารณะ [] getArrayValues () {return arrayValues; } โมฆะสาธารณะ setarrayValues (String [] arrayValues) {this.arrayValues = arrayValues; } // แผนที่คอลเลกชันแผนที่ส่วนตัวแผนที่; แผนที่สาธารณะ getMapValues () {return mapValues; } โมฆะสาธารณะ setMapValues (แผนที่ mapValues) {this.mapValues = mapValues; -คลาสนี้ห่อหุ้มชุดที่ใช้กันทั่วไปหลายชุด หากคุณต้องการแปลงเป็นแบบจำลองเชิงสัมพันธ์คุณต้องดูการแมปด้านล่าง
4. การทำแผนที่คอลเลกชัน
การทำแผนที่ของคอลเลกชันนั้นค่อนข้างง่าย คุณจะต้องเพิ่มแท็กคอลเลกชันที่เกี่ยวข้องเท่านั้น Hibernate จัดเตรียมแท็กคอลเลกชัน <et>, <pal>, <list> และ <rray> ตามลำดับ คอลเลกชันถูกแมปเข้ากับตารางความสัมพันธ์ที่สอดคล้องกันโดยใช้แท็กส่วนกลาง นอกจากนี้ความสัมพันธ์ของคีย์ต่างประเทศสามารถทำได้โดยการเพิ่มแท็ก <hey> และแอตทริบิวต์อื่น ๆ จะถูกเพิ่มโดยใช้ <Element>
CollectionMapping.hbm.xml
<? xml version = "1.0"?> <! doctype hibernate-mapping สาธารณะ "-// hibernate/hibernate mapping dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" table = "t_collection_mapping"> <id name = "id"> <generator // id> <property name = "name"/> <set name = "setValues" table = "t_set_values"> <key column = "set_id"> </key> table = "t_list_values"> <key column = "list_id"/> <list-index column = "list_index"/> <องค์ประกอบประเภท = "สตริง" คอลัมน์ = "list_value"/> </list> <map name = "mapvalues" table = "t_map_values" type = "string" column = "map_value"/> </map> <array name = "arrayValues" table = "t_array_value"> <key column = "array_id"/> <column index = "array_index" type = "integer">
ควรสังเกตว่าแท็กรายการและแท็กอาร์เรย์ วัตถุในสองชุดนี้อยู่ในลำดับ ดังนั้นเมื่อเพิ่มแท็กการแมปคุณจะต้องใช้รายการดัชนีหรือแท็กดัชนีเพื่อระบุลำดับของวัตถุ ยิ่งกว่านั้นเมื่อเพิ่มแท็กย่อยคุณต้องเพิ่มตามลำดับ กล่าวคือก่อนเพิ่มแท็ก <key> จากนั้นเพิ่มแท็ก <list-index> ในที่สุดและในที่สุดก็เพิ่มแท็ก <Element> มิฉะนั้นข้อผิดพลาดต่อไปนี้จะปรากฏขึ้น:
The content of element type "list" must match "(meta*,subselect?,cache?,synchronize*,comment?,key,(index|list-index),(element|one-to-many|many-to-many|composite-element|many-to-any),loader?,sql-insert?,sql-update?,sql-delete?,sql-delete-all?,filter*)".
5. แบบจำลองเชิงสัมพันธ์
โมเดลวัตถุที่กำหนดค่าจะถูกแปลงเป็นโมเดลเชิงสัมพันธ์ที่สอดคล้องกันและคำสั่ง SQL ที่สร้างขึ้นมีดังนี้:
เปลี่ยนตาราง t_array_value drop key ต่างประเทศ fk2e0dd0c067676b68 การเปลี่ยนแปลงตาราง t_list_values วางคีย์ต่างประเทศ fke01ec98bf4fcb03 การเปลี่ยนแปลงตาราง t_map_values drop key fkd169ba107402b585 FK7BB8D04A7E79F8BF DROP TABLE ถ้ามี T_ARRAY_VALUE TABLE หากมี T_COLLECTION_MAPPPED ตารางการวางถ้ามี T_LIST_VALUES TABLE TABLE ถ้ามี T_MAP_VALUES TABLE IF NULD) array_index จำนวนเต็มไม่ใช่ NULL, คีย์หลัก (array_id, array_index)) สร้างตาราง t_collection_mapping (ID จำนวนเต็มไม่ใช่ null auto_increment, ชื่อ varchar (255), คีย์หลัก (id)) สร้างตาราง t_list_value varchar (255) (MAP_ID จำนวนเต็มไม่ใช่ NULL, MAP_VALUE VARCHAR (255), MAP_KEY VARCHAR (255) NOL NULL, คีย์หลัก (MAP_ID, MAP_KEY)) สร้างตาราง t_set_values (set_id integer ไม่ใช่ null, set_value varchar (255)) ข้อ จำกัด FK2E0DD0C067676B68 คีย์ต่างประเทศ (array_id) การอ้างอิง t_collection_mapping (id) เปลี่ยนตาราง t_list_values เพิ่มดัชนี fke01ec98bf4fcb03 (list_id) เพิ่มข้อ จำกัด fke01ec98bf4fcb03 T_MAP_VALUES เพิ่มดัชนี FKD169BA107402B585 (MAP_ID), เพิ่มข้อ จำกัด FKD169BA107402B585 คีย์ต่างประเทศ (MAP_ID) การอ้างอิง T_COLLECTION_MAPPANC (ID) เปลี่ยนตาราง T_SET_VALUES fk7bb8d04a7e79f8bf คีย์ต่างประเทศ (set_id) อ้างอิง t_collection_mapping (id)
มุมมองฐานข้อมูลที่เกี่ยวข้องที่สร้างขึ้นมีดังนี้:
2. การทำงานของข้อมูล
1. การเขียนข้อมูล
เมื่อเขียนการดำเนินการข้อมูลคุณต้องใส่ใจในการสร้างวัตถุข้อมูลเมื่อเขียนข้อมูล รายการตั้งค่าและแผนที่จำเป็นต้องสร้างวัตถุข้อมูลและเขียนวัตถุข้อมูลไปยังฐานข้อมูล เนื่องจากทั้งสามนั้นเป็นอินเทอร์เฟซวัตถุคุณต้องสร้างวัตถุและเขียนวัตถุไปยังฐานข้อมูล รหัสเฉพาะมีดังนี้:
@suppresswarnings ({"ไม่ได้ตรวจสอบ", "rawtypes"}) โมฆะสาธารณะ testsave () {เซสชันเซสชัน = null; ลอง {session = hibernateutils.getSession (); session.beginTransaction (); CollectionMapping CM = new CollectionMapping (); CM.SetName ("จาง"); set set = new hashset (); set.add ("a"); set.add ("b"); CM.SetSetValues (SET); รายการรายการ = new ArrayList (); list.add ("list1"); list.add ("list2"); CM.SetListValues (รายการ); สตริง [] str = สตริงใหม่ [] {"array1", "array2"}; CM.SetArrayValues (STR); แผนที่แผนที่ = ใหม่ hashmap (); map.put ("k1", "v1"); map.put ("k2", "v2"); CM.SetMapValues (แผนที่); เซสชัน Save (CM); session.getTransaction (). commit (); } catch (exception e) {e.printstacktrace (); session.getTransaction (). ย้อนกลับ (); } ในที่สุด {hibernateutils.closesession (เซสชัน); -คำสั่ง SQL ที่สร้างขึ้นมีดังนี้:
ไฮเบอร์เนต: แทรกลงใน t_collection_mapping (ชื่อ) ค่า (?) hibernate: แทรกลงใน t_set_values (set_id, set_value) ค่า (?,?) ไฮเบอร์เนต: แทรกลงใน t_set_values (set_id, set_value) list_value) ค่า (?,?,?) ไฮเบอร์เนต: แทรกลงใน t_list_values (list_id, list_index, list_value) ค่า (?,?,?) ไฮเบอร์เนต: แทรกลงใน t_list_values (list_id, list_index, list_value) list_index, list_value) ค่า (?,?,?) ไฮเบอร์เนต: แทรกลงใน t_map_values (map_id, map_key, map_value) ค่า (?,?,?) ฮิเบอร์เนต: แทรกลงใน t_map_values (map_id, map_key, map_value) (array_id, array_index, array_value) ค่า (?,?,?) ไฮเบอร์เนต: แทรกลงใน t_array_value (array_id, array_index, array_value) ค่า (?,?)
2. การโหลดข้อมูล
วิธีการโหลดข้อมูลนั้นง่ายมาก มันจะโหลดข้อมูลในตารางลงในวัตถุตามชุดและจากนั้นคุณจะต้องได้รับการรวบรวมวัตถุที่สอดคล้องกันเท่านั้น
public void testload () {เซสชันเซสชัน = null; ลอง {session = hibernateutils.getSession (); session.beginTransaction (); collectionmapping cm = (collectionmapping) เซสชันโหลด (collectionmapping.class, 1); System.out.println ("cm.name ="+cm.getName ()); System.out.println ("cm.list ="+cm.getlistvalues ()); System.out.println ("cm.map ="+cm.getmapvalues ()); System.out.println ("cm.array ="+cm.getarrayvalues ()); System.out.println ("cm.set ="+cm.getSetValues ()); session.getTransaction (). commit (); } catch (exception e) {e.printstacktrace (); session.getTransaction (). ย้อนกลับ (); } ในที่สุด {hibernateutils.closesession (เซสชัน); -ผลลัพธ์ที่สร้างขึ้น:
Hibernate: เลือกคอลเลกชัน 0_.id เป็น id0_0_, collection0_.name เป็น name0_0_ จาก t_collection_mapping collection0_ โดยที่คอลเลกชัน 0_.id =? Hibernate: เลือก arrayValue0_.array_id เป็น array1_0_, arrayValue0_.array_value เป็น array2_0_, arrayvalue0_.array_index เป็น array3_0_ จาก t_array_value arrayvalue0_ cm.name = zhangsan ไฮเบอร์เนต: เลือก ListValues0_.list_id เป็น list1_0_, listvalues0_.list_value เป็น list2_0_, listvalues0_.list_index เป็น list3_0_ จาก t_list_values listvalues0_ cm.list = [list1, list2] hibernate: เลือก mapvalues0_.map_id เป็น map1_0_, mapvalues0_.map_value เป็น map2_0_, mapvalues0_.map_key เป็น map3_0_ จาก t_map_values mapvalues0_ ที่ไหน cm.map = {k1 = v1, k2 = v2} cm.array = [ljava.lang.string;@758d8478 ไฮเบอร์เนต: เลือก setValues0_.set_id เป็น set1_0_, setValues0_.set_value cm.set = [b, a] 3. สรุป
Hibernate สามารถคงอยู่อินสแตนซ์ของคอลเลกชัน Java ต่อไปนี้รวมถึง java.util.map, java.util.set, java.util.sortedmap, java.util.sortedset, java.util.list และอาร์เรย์ของหน่วยงานหรือค่าที่ถาวร คุณสมบัติของ type java.util.collection หรือ java.util.list ยังสามารถคงอยู่โดยใช้ความหมาย "กระเป๋า" คอลเลกชันที่ใช้สำหรับการคงอยู่ไม่สามารถรักษาความหมายที่แนบมากับคลาสใด ๆ ที่ใช้อินเทอร์เฟซเหล่านี้ยกเว้นอินเทอร์เฟซคอลเลกชัน (ตัวอย่างเช่น: คำสั่งซ้ำที่นำโดย LinkedHashSet) คอลเลกชันถาวรทั้งหมดทำงานได้โดยตรงตามความหมายของ HashMap, Hashset, Treemap, Treeet และ ArrayList ในการทำให้มันลึกซึ้งยิ่งขึ้นสำหรับคุณสมบัติที่มีคอลเลกชันประเภท Java จะต้องถูกกำหนดเป็นอินเทอร์เฟซ (นั่นคือแผนที่ชุดหรือรายการ ฯลฯ ) และต้องไม่เป็น Hashmap, Treeset หรือ ArrayList เหตุผลสำหรับข้อ จำกัด นี้คือเมื่อคุณไม่ทราบ Hibernate แอบแทนที่แผนที่ตั้งค่าและรายการอินสแตนซ์ของคุณด้วยการใช้งานแผนที่ตั้งค่าหรือรายการ (ดังนั้นในโปรแกรมของคุณให้ใช้ตัวดำเนินการ == ด้วยความระมัดระวัง) (หมายเหตุ: สำหรับประสิทธิภาพและเหตุผลอื่น ๆ อินเทอร์เฟซคอลเลกชัน Java เกือบทั้งหมดจะถูกนำไปใช้ในไฮเบอร์เนต (เพื่อใช้คุณสมบัติบางอย่างของการโหลดขี้เกียจ)) คลาสคอลเลกชันที่สั่งซื้อทั้งหมด (แผนที่รายการอาร์เรย์) มีคีย์หลัก ในกรณีนี้การอัปเดตของคลาสคอลเลกชันนั้นมีประสิทธิภาพมาก - คีย์หลักได้รับการจัดทำดัชนีอย่างมีประสิทธิภาพดังนั้นเมื่อไฮเบอร์เนตพยายามอัปเดตหรือลบแถวข้อมูลของแถวนั้นสามารถพบได้อย่างรวดเร็ว คีย์หลักของชุด (ชุด) ประกอบด้วย <sey> และฟิลด์องค์ประกอบอื่น ๆ สิ่งนี้ไม่มีประสิทธิภาพสำหรับองค์ประกอบบางประเภทโดยเฉพาะอย่างยิ่งองค์ประกอบการรวมกันหรือข้อความขนาดใหญ่หรือเขตข้อมูลไบนารีขนาดใหญ่ ฐานข้อมูลอาจไม่สามารถจัดทำดัชนีคีย์หลักที่ซับซ้อนได้อย่างมีประสิทธิภาพ ในทางกลับกันสำหรับการเชื่อมโยงแบบหนึ่งถึงหลายต่อหลายครั้งโดยเฉพาะตัวระบุสังเคราะห์ชุดสามารถบรรลุประสิทธิภาพที่มีประสิทธิภาพเหมือนกัน (ส่วนที่ 1: หากคุณต้องการให้ SchemaExport สร้างคีย์หลักสำหรับ <et> ของคุณคุณต้องประกาศว่าฟิลด์ทั้งหมดเป็น not-null = "true") แผนที่ <idbag> กำหนดคีย์พร็อกซีดังนั้นจึงสามารถอัปเดตได้อย่างมีประสิทธิภาพ ในความเป็นจริง <idbag> มีประสิทธิภาพที่ดีที่สุด กระเป๋าเป็นสิ่งที่เลวร้ายที่สุด เนื่องจากกระเป๋าอนุญาตให้ค่าองค์ประกอบที่ซ้ำกันและไม่มีฟิลด์ดัชนีจึงเป็นไปไม่ได้ที่จะกำหนดคีย์หลัก ไฮเบอร์เนตไม่สามารถกำหนดบรรทัดที่ซ้ำกันได้ เมื่อมีการเปลี่ยนแปลงคอลเลกชันดังกล่าว Hibernate จะลบคอลเลกชันทั้งหมดทั้งหมด (ผ่านการลบครั้งเดียว) ก่อนแล้วจึงสร้างคอลเลกชันทั้งหมดใหม่ ดังนั้นกระเป๋าจึงไม่มีประสิทธิภาพมาก