ในฐานะที่เป็นกรอบ ORM ไฮเบอร์เนตจะต้องตอบสนองความต้องการของเราในการใช้ความสัมพันธ์ระหว่างตาราง การใช้ไฮเบอร์เนตในวิธีการเชื่อมโยงนั้นง่ายมาก มาดูวิธีการแบบตัวต่อตัว:
โดยไม่ต้องกังวลใจเพิ่มเติมเราเพียงแค่อัปโหลดรหัส:
สองเอนทิตีคลาส Tuser และ Tpassport:
TUSER ระดับสาธารณะใช้ SerialIzable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUid = 1L; ID int ส่วนตัว; อายุ int ส่วนตัว; ชื่อสตริงส่วนตัว; หนังสือเดินทาง TPassport ส่วนตัว; // omit get/set method} คลาสสาธารณะ tpassport ดำเนินการ serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUid = 1l; ID int ส่วนตัว; สตริงส่วนตัวอนุกรม; Int หมดอายุส่วนตัว ผู้ใช้ TUSER ส่วนตัว // omit get/set method}ลองมาดูความแตกต่างระหว่างไฟล์การแมป:
<hibernate-mapping package = "org.hibernate.tutorial.domain4"> <class name = "tuser" table = "user4"> <id name = "id" คอลัมน์ = "id"> <generator/> </id> <property name = "name" type = "java.lang.string คอลัมน์ = "อายุ"/> <ชื่อแบบหนึ่งต่อหนึ่ง = "หนังสือเดินทาง" cascade = "all" outer-join = "true"/> </class> </hibernate-mapping>
ที่นี่เราเห็นฉลากใหม่หนึ่งต่อหนึ่งซึ่งแสดงให้เห็นว่าคลาสปัจจุบันและคลาสที่สอดคล้องกันเป็นแบบหนึ่งต่อหนึ่งน้ำตกเป็นความสัมพันธ์แบบเรียงซ้อนกันทั้งหมดแสดงให้เห็นว่าไม่ว่าสถานการณ์จะเป็นเช่นไร Outer-join หมายถึงว่าจะใช้คำสั่งการเข้าร่วมด้านนอกหรือไม่
ลองดูที่ไฟล์การแมป Tpassport อื่น ๆ :
<hibernate-mapping package = "org.hibernate.tutorial.domain4"> <class name = "tpassport" table = "Passport4"> <id name = "id" คอลัมน์ = "id"> <generator> <param name = "คุณสมบัติ"> ผู้ใช้ </param> </generator name = "expiry" type = "java.lang.integer" คอลัมน์ = "หมดอายุ"/> <one-to-name = "user" constrained = "true"/> </class> </hibernate-mapping>
ที่นี่เรามุ่งเน้นไปที่ค่าคลาสของเครื่องกำเนิดไฟฟ้า มันระบุคีย์การอ้างอิงต่างประเทศสำหรับต่างประเทศและการอ้างอิงใดที่ระบุโดย param ซึ่งระบุ ID ของคลาสผู้ใช้อ้างอิง มีคุณสมบัติที่มีข้อ จำกัด เพิ่มเติมในแท็กแบบหนึ่งต่อหนึ่งซึ่งบอก Hibernate ว่ามีข้อ จำกัด ของคีย์ต่างประเทศในคลาสปัจจุบันนั่นคือ ID ของคลาสปัจจุบันถูกสร้างขึ้นตาม ID ของ TUSER
มาอัปโหลดคลาสทดสอบโดยตรง เวลานี้คลาสทดสอบไม่ได้ใช้ Junit แต่มาพร้อมกับวิธีการหลักโดยตรง:
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {การกำหนดค่า cfg = การกำหนดค่าใหม่ (). configure (); SessionFactory SessionFactory = cfg.buildsessionFactory (); เซสชัน = sessionfactory.opensession (); session.beginTransaction (); ผู้ใช้ TUSER = TUSER ใหม่ (); user.setage (20); user.setName ("shuntest"); TPassport Passport = new TPassport (); Passport.setexpiry (20); Passport.setserial ("123123123"); Passport.setUser (ผู้ใช้); user.setPassport (หนังสือเดินทาง); session.save (ผู้ใช้); session.getTransaction (). commit (); -รหัสนั้นง่ายมากดังนั้นฉันจะไม่พูดถึงมัน มาดูกันที่นี่เป็นหลัก:
session.save (ผู้ใช้);
ทำไมเราถึงโทรเพียงครั้งเดียวบันทึกที่นี่? เหตุผลก็คือคุณสมบัติ Cascade ในไฟล์การแมป TUSER ของเราถูกตั้งค่าเป็นทั้งหมดซึ่งหมายความว่าเมื่อเราบันทึกอัปเดตลบ ฯลฯ บน TUSER TPSPORT จะดำเนินการที่สอดคล้องกันดังนั้นเราไม่จำเป็นต้องเขียนเซสชัน SAVE (หนังสือเดินทาง) เราเห็นพื้นหลัง:
Hibernate: แทรกลงใน user4 (ชื่ออายุ) ค่า (?,?) Hibernate: แทรกลงใน Passport4 (อนุกรม, หมดอายุ, id) ค่า (?,?,?)Hibernate: พิมพ์สองข้อความโดยพิสูจน์ว่า Hibernate ได้ทำงานนี้ให้เราแล้ว
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {การกำหนดค่า cfg = การกำหนดค่าใหม่ (). configure (); SessionFactory SessionFactory = cfg.buildsessionFactory (); เซสชัน = sessionfactory.opensession (); tuser user = (tuser) เซสชันโหลด (tuser.class, จำนวนเต็มใหม่ (3)); System.out.println (user.getName ()+":"+user.getPassport (). getSerial ()); - ที่นี่เราสอบถามคลาส TUSER และรับวัตถุ tpassport สมาคมคีย์ต่างประเทศ
ทีนี้ลองมาดูสมาคมแบบหนึ่งต่อหนึ่งที่สร้างความสัมพันธ์ผ่านคีย์ต่างประเทศ
มันยังคงเหมือนกับตัวอย่าง: เราเขียนสองคลาสเอนทิตี TGROUP และ TUSER
TGROUP ระดับสาธารณะใช้ serializable {ส่วนตัวคงที่สุดท้าย Long SerialVersionUID = 1L; ID int ส่วนตัว; ชื่อสตริงส่วนตัว; ผู้ใช้ TUSER ส่วนตัว // omit get/set method} tuser คลาสสาธารณะใช้ serializable {ส่วนตัวคงที่สุดท้าย long serialVersionUid = 1l; ID int ส่วนตัว; อายุ int ส่วนตัว; ชื่อสตริงส่วนตัว; กลุ่ม Tgroup ส่วนตัว; // omit get/set method} หลังจากคลาสเอนทิตีเสร็จแล้วลองดูที่ไฟล์การแมป:
<hibernate-mapping package = "org.hibernate.tutorial.domain5"> <class name = "tuser" table = "user5"> <id name = "id" คอลัมน์ = "id"> <generator/> </id> <property name = "name" type = "java.lang.string column = "age"/> <multy-to-name = "Group" column = "group_id" unique = "true"/> </class> </hibernate-mapping>
ที่นี่เราเห็นว่ามีการใช้แท็กแบบหลายต่อหนึ่งแทนที่จะเป็นแบบหนึ่งต่อหนึ่ง ทำไม
ฉันไม่ได้ให้ความสนใจมากนักเมื่อฉันใช้มันมาก่อน อย่างไรก็ตามฉันสามารถใช้มันได้ แต่หลังจากอ่านหนังสือของ Xia Xin ในครั้งนี้ในที่สุดฉันก็เข้าใจว่าในความเป็นจริงวิธีการเชื่อมโยงผ่านคีย์ต่างประเทศเป็นเพียงวิธีพิเศษของหลาย ๆ คน เรา จำกัด ผ่านที่ไม่ซ้ำกัน = "จริง" ที่ต้องมีเพียงหนึ่งเดียวนั่นคือการเชื่อมโยงแบบหนึ่งต่อหนึ่ง
ถัดไปลองดูที่ไฟล์การแมปของ Tgroup:
<hibernate-mapping package = "org.hibernate.tutorial.domain5"> <class name = "tgroup" table = "Group5"> <id name = "id" คอลัมน์ = "id"> <generator/> </id> <property name = "name" type = "java.lang </hibernate-mapping>
ที่นี่โปรดทราบว่าเราใช้แบบหนึ่งต่อหนึ่งอีกครั้งระบุว่าเอนทิตีปัจจุบันและ TUSER เป็นแบบหนึ่งต่อหนึ่ง ที่นี่เราไม่ได้ใช้แบบหลายต่อหนึ่ง แต่ระบุว่าแอตทริบิวต์ใดในเอนทิตี TUSER เพื่อเชื่อมโยง TGROUP คลาสปัจจุบัน ที่นี่เราระบุว่า TUSER เกี่ยวข้องกับ TUSER ผ่านคุณลักษณะกลุ่ม Property-Ref ระบุว่าคุณสมบัติใดที่จะเชื่อมโยง
มาดูคลาสทดสอบด้านล่าง:
ชั้นเรียนสาธารณะ hibernatetest {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {การกำหนดค่า cfg = การกำหนดค่าใหม่ (). configure (); SessionFactory SessionFactory = cfg.buildsessionFactory (); เซสชัน = sessionfactory.opensession (); session.beginTransaction (); กลุ่ม tgroup = ใหม่ tgroup (); group.setName ("TestGroup"); ผู้ใช้ TUSER = TUSER ใหม่ (); user.setage (23); user.setName ("ทดสอบ"); user.setGroup (กลุ่ม); group.setUser (ผู้ใช้); เซสชัน SAVE (กลุ่ม); session.save (ผู้ใช้); session.getTransaction (). commit (); session.close (); - โปรดทราบว่ารหัสของเราจะต้องได้รับการบันทึกสองครั้งในครั้งนี้เนื่องจากมีการติดต่อที่สอดคล้องกันซึ่งกันและกัน การประหยัดเพียงหนึ่งเดียวจะไม่ทำให้เกิดการดำเนินการใด ๆ ดังนั้นเราต้องโทรหาการดำเนินการที่บันทึกไว้สองครั้ง ในที่สุดก็ส่ง
ไฮเบอร์เนตพิมพ์คำสั่ง:
ไฮเบอร์เนต: แทรกลงในกลุ่ม 5 (ชื่อ) ค่า (?) ไฮเบอร์เนต: แทรกลงใน user5 (ชื่อ, อายุ, group_id) ค่า (?,?,?)
ซึ่งหมายความว่าเราเก็บค่าวัตถุสองค่าไว้อย่างถูกต้อง
เราเขียนคลาสทดสอบเพิ่มเติมเพื่อสอบถาม:
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {การกำหนดค่า cfg = การกำหนดค่าใหม่ (). configure (); SessionFactory SessionFactory = cfg.buildsessionFactory (); เซสชัน = sessionfactory.opensession (); tuser user = (tuser) เซสชันโหลด (tuser.class, จำนวนเต็มใหม่ (1)); System.out.println ("จากผู้ใช้ Get Group:"+user.getGroup (). getName ()); กลุ่ม tGroup = (tGroup) เซสชันโหลด (tgroup.class, จำนวนเต็มใหม่ (1)); System.out.println ("จากกลุ่มรับผู้ใช้:" + group.getUser (). getName ()); session.close (); - เราทั้งคู่สามารถได้รับผลลัพธ์ที่ถูกต้องซึ่งแสดงให้เห็นว่าเราสามารถนำค่านิยมของผู้อื่นผ่านวัตถุสองชิ้นเพื่อให้บรรลุเป้าหมายของเรา
tgroup และ tuser ที่ใช้ในตัวอย่างนี้เป็นเพียงตัวอย่าง ในความเป็นจริงผู้ใช้ในชีวิตจริงโดยทั่วไปสอดคล้องกับหลายกลุ่ม