การแมปคีย์หลักคอมโพสิตต้องใช้แท็ก <pomposite-id> ในไฟล์การกำหนดค่าการแมป แท็กนี้หมายถึงการระบุคลาสเป็นคีย์หลักของสารประกอบที่สอดคล้องกัน แอตทริบิวต์ชื่อจำเป็นต้องระบุค่าคุณสมบัติที่กำหนดไว้ในไฟล์คลาสและเพิ่ม <-property> label sub-label ลงในแท็ก
หมายเหตุ: หากคุณต้องการใช้การแมปคอมโพสิตคุณจะต้องวางคีย์หลักคอมโพสิตในคลาสเดียวนั่นคือแอตทริบิวต์คีย์หลักคอมโพสิตและแอตทริบิวต์อื่น ๆ จะแบ่งออกเป็นสองคลาส
คีย์หลักของความสัมพันธ์การแมปของคีย์หลักคอมโพสิตประกอบด้วยหลายคอลัมน์ซึ่งสอดคล้องกับตารางข้อมูลค่อนข้างง่ายดังแสดงในรูปด้านล่าง:
1. ไฟล์คลาส
ที่นี่เราใช้ตารางในรูปด้านบนเป็นตัวอย่าง ในตารางสองฟิลด์และระยะเวลารวมกันเพื่อสร้างคีย์หลักของตาราง ดังนั้นคลาสใหม่ที่แบ่งออกเป็นชื่อ fiscalyearperiod และ fiScalyeArperiodpk ตามลำดับ ในหมู่พวกเขาคลาส FISCALYEARPERIOD ห่อหุ้มคุณลักษณะหลักหลักของตารางคลาส FISCALYEARPERIOD จะห่อหุ้มคุณลักษณะอื่น ๆ และคลาส FISCALYEARPERIOD
1.1 FISCALYEARPERIOD.JAVA
คลาสห่อหุ้มคุณสมบัติพื้นฐานและห่อหุ้มคลาส fiscalyearperiodpk เป็นแอตทริบิวต์ลงในคลาสและกำหนดค่าการแมปที่สอดคล้องกันในไฟล์การกำหนดค่าดังต่อไปนี้:
แพ็คเกจ com.src.hibernate; นำเข้า java.sql.date; Public Class FISCALYEARPERIOD {// เวลาหลักคีย์หลัก fiScalyeArperiodpk ficalyearperiodpk; Public FiScalyeArperiodpk getFiscalyeArperiodpk () {return fiScalyeArperiodpk; } โมฆะสาธารณะ setFiscalyeArperiodpk (fisalyearperiodpk fiscalyearperiodpk) {this.fiscalyearperiodpk = fisalyearperiodpk; } // วันที่เริ่มต้นวันที่ส่วนตัวเริ่มต้น; วันที่สาธารณะ getBegindate () {return begindate; } โมฆะสาธารณะ setBegIndate (วันที่ Begindate) {this.begindate = Begindate; } // วันที่สิ้นสุดวันที่ส่วนตัวสิ้นสุด; วันที่สาธารณะ getEnddate () {return enddate; } โมฆะสาธารณะ setEndDate (วันที่สิ้นสุด) {this.endDate = enddate; } // ระยะเวลาระยะเวลาสตริงส่วนตัวของสตริง; Public String getPeriodsts () {ส่งคืนระยะเวลา; } โมฆะสาธารณะ setPeriodSts (สตริงระยะเวลา) {this.periodsts = Tuptsts; - 1.2 FISCALYEARPERIODPK.JAVA
ห่อหุ้มแอตทริบิวต์คีย์หลัก คลาสนี้ถูกแยกออกจากคลาส fiscalyearperiod มันมีแอตทริบิวต์คีย์หลักพื้นฐานและจำเป็นต้องใช้อินเตอร์เฟส serializable คลาสนี้จะถูกแมปกับแท็ก <pomposite-id> ในไฟล์กำหนดค่าเพื่อระบุคลาส รหัสมีดังนี้:
แพ็คเกจ com.src.hibernate; นำเข้า java.io.serializable; Public Class FISCALYEARPERIODPK ใช้ SerialIzable {// ปีที่เป็นส่วนตัว public int getFiscalyear () {return fiscalyear; } โมฆะสาธารณะ setFiscalyear (int fiscalyear) {this.fiscalyear = fisalyear; } // ระยะเวลาระยะเวลา int fiscalperiod; public int getFiscalperiod () {return fiscalperiod; } โมฆะสาธารณะ setFiscalPeriod (int fiscalperiod) {this.fiscalperiod = fiscalperiod; - 2. ไฟล์กำหนดค่า
นี่คือคำถามใดที่คลาสใดที่ต้องเพิ่มไฟล์การแมป เนื่องจากมีการใช้แท็ก <pomposite-Id> คุณจะต้องเพิ่มการแมปสำหรับคลาส fiScalyeArperiod เพิ่มแท็กคีย์หลักคอมโพสิตที่สอดคล้องกันลงในไฟล์การแมปและเพิ่มแอตทริบิวต์คีย์หลักที่สอดคล้องกันลงในแท็กดังต่อไปนี้:
<? 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_fiscal_year_period_pk"> <composite-id name = "fiscalyeArpk"> <key-property name = "fisalyear"> </key-property> <key-property name = "fiscalperiod"> </key-property> type = "date"/> <property name = "enddate" type = "date"/> <property name = "triportsts"/> </class> </hibernate-mapping>
ไฟล์ด้านบนถูกสร้างขึ้นเพื่อสร้างตารางฐานข้อมูลที่เกี่ยวข้องและคำสั่ง SQL ที่สร้างขึ้นมีดังนี้:
ตารางวางถ้ามีอยู่ t_fiscal_year_period_pk สร้างตาราง t_fiscal_year_period_pk (จำนวนเต็ม fisalyear ไม่ใช่ null, จำนวนเต็ม fiscalperiod ไม่ว่าง, วันที่, วันที่สิ้นสุด, ระยะเวลา, Varchar (255), คีย์หลัก
โครงสร้างตารางที่สอดคล้องกันมีดังนี้:
3. การทำงานของข้อมูล
หลังจากกำหนดค่าไฟล์การแมปที่สอดคล้องกันการดำเนินการข้อมูลที่เกี่ยวข้องจะง่ายมาก ก่อนอื่นเริ่มต้นด้วยการเขียนข้อมูล เมื่อเขียนข้อมูลไปยังฐานข้อมูลสองคลาสจะถูกเขียนลงในฐานข้อมูลในเวลาเดียวกัน ดังนั้นทั้งสองคลาสจะต้องถูกแปลงเป็นสถานะชั่วคราว ดังนั้นเมื่อบันทึกคุณต้องบันทึกวัตถุ fisalearperiod ไปยังฐานข้อมูลก่อนก่อนจากนั้นจะเชื่อมโยงแอตทริบิวต์คอมโพสิตโดยอัตโนมัติและบันทึกข้อมูลลงในฐานข้อมูลโดยอัตโนมัติ
3.1 การดำเนินการเขียน
วิธีการเขียนการเขียนเหมือนกับวิธีการเขียนก่อนหน้า คุณต้องกำหนดวัตถุสองวัตถุจากนั้นบันทึกข้อมูลวัตถุที่เกี่ยวข้องลงในฐานข้อมูล รหัสมีดังนี้:
โมฆะสาธารณะ testsave1 () {// ประกาศเซสชันวัตถุเซสชันเซสชัน = null; ลอง {// รับ Session Object Session = HiberNateUtils.getSession (); // เปิดเซสชันเซสชัน BEGINTRANSACTION (); // สร้างวัตถุคอมโพสิต FISCALYEARPERIODPK FISCALYEARPERIODPK = ใหม่ FISCALYEARPERIODPK (); FISCALYEARPERIODPK.SETFISCALPERIOD (2014); FISCALYEARPERIODPK.SETFISCALYEARYEAR (2012); // สร้างวัตถุ fiScalyeArperiod fiScalyeArperiod = ใหม่ fiScalyeArperiod (); FISCALYEARPERIOD.SETFISCALYEARPERIODPK (FISCALYEARPERIODPK); เซสชัน SAVE (FISCALYEARPERIOD); // ส่งเซสชันเซสชัน Session.getTransaction (). commit (); } catch (exception e) {e.printstacktrace (); session.getTransaction (). ย้อนกลับ (); } ในที่สุด {hibernateutils.closesession (เซสชัน); -ดำเนินการวิธีการทดสอบที่สอดคล้องกันและคำสั่ง SQL ที่สร้างขึ้นมีดังนี้:
Hibernate: insert into t_fiscal_year_period_pk (beginDate, endDate, periodSts, fiscalYear, fiscalPeriod) values (?, ?, ?, ?, ?) มุมมองฐานข้อมูลที่เกี่ยวข้อง:
3.2 การดำเนินการโหลด
วิธีการโหลดที่สอดคล้องกันจะแตกต่างจากก่อนหน้านี้เนื่องจากคีย์หลักในตารางเป็นคุณสมบัติผสมดังนั้นจึงต้องสร้างคลาส เมื่อโหลดข้อมูลคุณต้องสร้างวัตถุหลักหลัก ในเวลานี้คีย์หลักคือวัตถุและคุณต้องกำหนดค่าให้กับคุณสมบัติของวัตถุเพื่อรับวัตถุ รหัสมีดังนี้:
โมฆะสาธารณะ testload1 () {// ประกาศเซสชันวัตถุเซสชันเซสชัน = null; ลอง {// รับ Session Object Session = HiberNateUtils.getSession (); // เปิดเซสชันเซสชัน BEGINTRANSACTION (); // สร้างวัตถุคอมโพสิต FISCALYEARPERIODPK FISCALYEARPERIODPK = ใหม่ FISCALYEARPERIODPK (); FISCALYEARPERIODPK.SETFISCALPERIOD (2014); FISCALYEARPERIODPK.SETFISCALYEAR (2012); FISCALYEARPERIOD FISCALYEARPERIOD = (FISCALYEARPERIOD) เซสชั่นโหลด (fISCALYEARPERIOD.CLASS, FISCALYEARPERIODPK); System.out.println ("วันที่เริ่มต้น:"+fisalearperiod.getBegindate ()); // ส่งเซสชันเซสชัน getTransaction (). commit (); } catch (exception e) {e.printstacktrace (); session.getTransaction (). ย้อนกลับ (); } ในที่สุด {hibernateutils.closesession (เซสชัน); -ผลลัพธ์มีดังนี้:
Hibernate: เลือก fiscalyear0_.fiscalyear เป็น fiscalyear0_0_, fiscalyear0_.fiscalperiod เป็น fiscalpe2_0_0_, fisalyear0_.begindate เป็น begindate0_0_, fisalyear0_.enddate t_fiscal_year_period_pk fiscalyear0_ โดยที่ fiscalyear0_.fiscalyear =? และ FISCALYEAR0_.FiscalPeriod =? วันที่เริ่มต้น: 2013-10-12
4. ตัวอย่างที่ครอบคลุม
ตารางแผนกของ บริษัท ขนาดใหญ่ (hibernate_dept_compositepk) ประกอบด้วยฟิลด์เช่นพื้นที่ (พื้นที่) ชื่อแผนก (ชื่อ) จำนวนคนในแผนก (Empcount) และเวลาการจัดตั้ง (วันเกิด) เราใช้พื้นที่และชื่อแผนกเป็นคีย์หลักร่วม:
4.1 คลาสเป้าหมาย: แผนก. Java
แผนกคลาสสาธารณะ { /** บทคัดย่อคุณลักษณะการเชื่อมโยงคีย์หลักและเขียนลงในคลาสแยกกัน* /// พื้นที่สตริงส่วนตัว; // ชื่อสตริงส่วนตัว; / ** การเตรียมวัตถุคลาสคีย์หลักเป็นตัวแปรสมาชิก*/ แผนกเอกชนแผนกแผนก; private int empcount; วันเกิดส่วนตัววันเกิด; // สตริงสาธารณะ getArea () {// พื้นที่ส่งคืน; //} // // โมฆะสาธารณะ setarea (พื้นที่สตริง) {// this.area = พื้นที่; //} // // สตริงสาธารณะ getName () {// ชื่อคืน; //} // // โมฆะสาธารณะ setName (ชื่อสตริง) {// this.name = name; //} public int getempcount () {return empcount; } โมฆะสาธารณะ setempCount (int empcount) {this.empcount = empCount; } วันที่สาธารณะ getBirthday () {ส่งคืนวันเกิด; } โมฆะสาธารณะ setBirthday (วันเกิดวันที่) {this.birthday = วันเกิด; } Public Departmentpk getDepartmentPk () {return Departmentpk; } โมฆะสาธารณะ setDepartmentpk (แผนกแผนก PK) {this.departmentPk = แผนก; - 4.2 คลาสคีย์หลัก: Departmentpk.java
Public Class Departmentpk ใช้ serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = -288002855915204255LL; พื้นที่สตริงส่วนตัว ชื่อสตริงส่วนตัว; /** * วิธีการเขียนทับ HashCode (ตัดสินตามพื้นที่และชื่อ) *///@Override Public Int HashCode () {Final Int Prime = 31; int ผลลัพธ์ = 1; result = prime * result + ((พื้นที่ == null)? 0: พื้นที่ hashCode ()); result = prime * result + ((name == null)? 0: name.hashCode ()); ผลการกลับมา; } / ** * overwrite เท่ากับ (ตัดสินตามพื้นที่และชื่อ) * / @Override บูลีนสาธารณะเท่ากับ (Object OBJ) {ถ้า (นี้ == OBJ) คืนค่าจริง; ถ้า (obj == null) ส่งคืนเท็จ; ถ้า (getClass ()! = obj.getClass ()) ส่งคืนเท็จ; Final DepartmentPK อื่น ๆ = (แผนก) OBJ; if (พื้นที่ == null) {ถ้า (อื่น ๆ . area! = null) ส่งคืนเท็จ; } else ถ้า (! are.equals (อื่น ๆ . area)) ส่งคืนเท็จ; if (name == null) {ถ้า (อื่น ๆ name! = null) return false; } อื่นถ้า (! name.equals (อื่น ๆ . name)) ส่งคืน false; กลับมาจริง; } สตริงสาธารณะ getArea () {พื้นที่ส่งคืน; } โมฆะสาธารณะ setarea (พื้นที่สตริง) {this.area = พื้นที่; } สตริงสาธารณะ getName () {ชื่อคืน; } โมฆะสาธารณะ setName (ชื่อสตริง) {this.name = name; - 4.3 Mapping File Department.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" name = "com.yangfei.hibernate.compositepk.entity.department" ตาราง = "hibernate_dept_compositepk"> <!-คีย์หลักของยูเนี่ยน-> <! name = "name" /> < /composite-id> <!-คุณสมบัติอื่น ๆ-> <property name = "empcount" length = "4" /> <property name = "วันเกิด" type = "วันที่" /> < /class> < /hibernate-mapping>
4.4 ไฟล์กำหนดค่าไฮเบอร์เนต hibernate.cfg.xml
<? XML เวอร์ชัน = '1.0' การเข้ารหัส = 'UTF-8'?> <! doctype hibernate-configuration สาธารณะ "-// hibernate/hibernate การกำหนดค่า dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-configuration-3 เครื่องมือ -> <hibernate-configuration> <session-factory> <property name = "Dialect"> org.hibernate.dialect.oraclec name = "connection.password"> yf123 </คุณสมบัติ> <property name = "connection.driver_class"> oracle.jdbc.driver.oracledriver </คุณสมบัติ> <property name = "hibernate.show_sql"> true </property> </session-factory> </hibernate-configuration>
4.5 ชั้นเรียนทดสอบ: Departmenttest.java
Public Class DepartmentTest ขยาย TestCase { / *** ทดสอบข้อมูลแทรก* / โมฆะสาธารณะบันทึก () {เซสชันเซสชัน = HiberNateUtils.getSession (); ธุรกรรม t = session.beginTransaction (); ลอง {แผนกแผนก = แผนกใหม่ (); / ** สร้างวัตถุหลักหลัก*/ Departmentpk Deptpk = New Departmentpk (); Deptpk.setarea ("ปักกิ่ง"); Deptpk.setName ("แผนก R&D"); Dept.SetDepartmentPK (Deptpk); dept.setempcount (100); Dept.SetBirthday (วันที่ใหม่ ()); เซสชัน SAVE (แผนก); T.Commit (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } ในที่สุด {hibernateutils.closesession (เซสชัน); }} / *** การทดสอบโหลดข้อมูล* / โมฆะสาธารณะโหลด () {เซสชันเซสชัน = hibernateutils.getSession (); ธุรกรรม t = session.beginTransaction (); ลอง { / ** สร้างวัตถุหลักหลัก* / Departmentpk Deptpk = New Departmentpk (); Deptpk.setarea ("ปักกิ่ง"); Deptpk.setName ("แผนก R&D"); แผนกแผนก = (แผนก) เซสชั่นโหลด (แผนก. คลาส, Deptpk); System.out.println (dept.getDepartmentPk (). getArea ()+","+dept.getDepartmentPk (). getName ()+","+dept.getEmpCount ()+"," dept.getBirthday (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } ในที่สุด {hibernateutils.closesession (เซสชัน); }} / *** ข้อมูลการปรับเปลี่ยนการทดสอบ* / การอัปเดตโมฆะสาธารณะ () {เซสชันเซสชัน = hibernateutils.getSession (); ธุรกรรม t = session.beginTransaction (); ลอง { / ** สร้างวัตถุหลักหลัก* / Departmentpk Deptpk = New Departmentpk (); Deptpk.setarea ("ปักกิ่ง"); Deptpk.setName ("แผนก R&D"); แผนก EMP = (แผนก) เซสชั่นโหลด (แผนก. คลาส, Deptpk); System.out.println (emp.getDepartmentPk (). getArea ()+","+emp.getDepartmentPk (). getName ()+","+emp.getempcount ()+"," emp.getBirthday (); emp.setempcount (100); Session.saveorupdate (EMP); / ** สร้างวัตถุหลักหลัก*/ Departmentpk Deptpk2 = New Departmentpk (); Deptpk2.setarea ("ปักกิ่ง"); Deptpk2.setName ("แผนก R&D"); แผนกแผนก = (แผนก) เซสชั่นโหลด (แผนก. คลาส, deptpk2); System.out.println (dept.getDepartmentPk (). getArea ()+","+dept.getDepartmentPk (). getName ()+","+dept.getEmpCount ()+"," dept.getBirthday (); T.Commit (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } ในที่สุด {hibernateutils.closesession (เซสชัน); }} / *** ทดสอบลบข้อมูล* / โมฆะสาธารณะลบ () {เซสชันเซสชัน = hibernateutils.getSession (); ธุรกรรม t = session.beginTransaction (); ลอง { / ** สร้างวัตถุหลักหลัก* / Departmentpk Deptpk = New Departmentpk (); Deptpk.setarea ("ปักกิ่ง"); Deptpk.setName ("แผนก R&D"); แผนกแผนก = (แผนก) เซสชั่นโหลด (แผนก. คลาส, Deptpk); session.delete (dept); T.Commit (); } catch (hibernateException e) {e.printStackTrace (); t.rollback (); } ในที่สุด {hibernateutils.closesession (เซสชัน); -