ไฟล์ฐานข้อมูลเริ่มต้นที่จำเป็นในบทความนี้มีรหัสตัวอย่างที่สมบูรณ์สำหรับการดำเนินการไฮเบอร์เนตทั่วไป (รวมถึงไฟล์ JAR ที่จำเป็นทั้งหมดสำหรับการดำเนินการไฮเบอร์เนต) มีไว้สำหรับการดาวน์โหลดและการเรียนรู้: http://download.csdn.net/detail/daijin888888/9551724444444
1. การทำแผนที่สมาคมไฮเบอร์เนต
1) การทำแผนที่สมาคมคืออะไร?
หากมีความสัมพันธ์ระหว่างตาราง Hibernate ช่วยให้เราสามารถอธิบายความสัมพันธ์ของพวกเขาใน HBM.XML และจากนั้นจะทำงานโดยอัตโนมัติในตารางความสัมพันธ์อื่นตามความสัมพันธ์นี้เมื่อเราทำงานหนึ่งในตาราง จากนั้นการตั้งค่าของความสัมพันธ์การเชื่อมโยงนี้เรียกว่าการทำแผนที่การเชื่อมโยง
2) การทำแผนที่สมาคมมีประโยชน์อย่างไร?
หลายตารางสามารถเชื่อมโยงกับการเยี่ยมชมครั้งเดียว
-ติดตามข้อมูลของตารางความสัมพันธ์เชื่อมโยง
-เชื่อมต่อข้อมูลใหม่และแก้ไขของตารางความสัมพันธ์
-ข้อมูลลบที่เกี่ยวข้องจากตารางความสัมพันธ์
3) ขั้นตอนการดำเนินการแมปการเชื่อมโยงการเชื่อมโยง
- ทำความเข้าใจความสัมพันธ์ระหว่างตารางและชี้แจงสาขาความสัมพันธ์
-ขยายแอตทริบิวต์การเชื่อมโยงในคลาสเอนทิตีเพื่อห่อหุ้มข้อมูลที่เกี่ยวข้อง
-คุณต้องกำหนดค่าไฟล์ HBM.XML และตั้งค่าความสัมพันธ์เกี่ยวกับการเชื่อมโยง
*2. สมาคมหนึ่งถึงหลายคน
ตัวอย่าง: หากบัญชีมีระเบียนบริการหลายรายการหวังว่าเมื่อสอบถามข้อมูลบัญชีจะทำการสอบถามข้อมูลบริการที่เกี่ยวข้องโดยอัตโนมัติ
1) ความสัมพันธ์ของตาราง
ความสัมพันธ์แบบหนึ่งถึงหลายคนฟิลด์ความสัมพันธ์คือ Service.account_id (นั่นคือจะต้องมี Account_id Field ที่เกี่ยวข้องกับตารางบัญชีในตารางบริการและฟิลด์นี้สอดคล้องกับ ID ในตารางบัญชี)
2) แอตทริบิวต์ความสัมพันธ์ต่อท้าย
ในคลาสบัญชีต่อท้ายบริการแอตทริบิวต์ที่เกี่ยวข้องซึ่งเป็นประเภทชุด <service>
เซตส่วนตัว <service> บริการ = ใหม่ HashSet <Service> ();
3) ตั้งค่าความสัมพันธ์
--ไวยากรณ์
ตั้งค่าความสัมพันธ์แบบหนึ่งถึงหลายคนในบัญชี hbm.xml
<set name = "Association Attribute Name"> <key column = "ชื่อฟิลด์เชื่อมโยง"/> <แบบหนึ่งต่อหลาย/> </set>-eMplement <set name = "services"> <key column = "account_id"/> <แบบหนึ่งต่อจำนวน/> </set>
4) ตัวอย่างรหัส
เป็นที่รู้จัก:
-บริการคุณลักษณะที่เกี่ยวข้อง
-บัญชีฟิลด์ที่เชื่อมโยงกัน _id
-บริการวัตถุที่เชื่อมโยง-> บริการชื่อตาราง
<span style = "ตัวอักษรขนาด: 14px;"> โมฆะสาธารณะ testfind () {เซสชันเซสชัน = hibernateutil.getSession (); บัญชี A = (บัญชี) เซสชันการโหลด (บัญชี. class, 1010); System.out.println ("--- แสดงข้อมูลบัญชีบัญชี ----"); System.out.println (A.getId () + "" + A.getRealName () + "" + A.GetIdCardno ()); System.out.println ("-แสดงบัญชีธุรกิจภายใต้บัญชีปัจจุบัน ----"); ตั้งค่า <services> services = a.getServices (); สำหรับ (บริการ s: บริการ) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } system.out.println (a.toString ()); } </span>*3. การเชื่อมโยงหลายต่อหนึ่ง
ตัวอย่าง: ฉันหวังว่าหลังจากสอบถามข้อมูลบริการฉันสามารถสอบถามข้อมูลบัญชีที่เกี่ยวข้องได้โดยอัตโนมัติ
1) ความสัมพันธ์
บริการและบัญชีมีความสัมพันธ์แบบหลายต่อหนึ่งและฟิลด์ความสัมพันธ์คือ Service.account_id
2) ผนวกแอตทริบิวต์ที่เกี่ยวข้อง
-ขยายบัญชีอสังหาริมทรัพย์ที่เกี่ยวข้องในคลาสเอนทิตีบริการประเภทของมันคือบัญชี
บัญชีบัญชีส่วนตัว
หลังจากนั้นแอตทริบิวต์ AccountID สามารถลบออกได้และค่าของบัญชี agcount_id สามารถรับได้ผ่านวิธี getAccount (). getId ()
3) ตั้งค่าความสัมพันธ์
. ไวยากรณ์:
-in service.hbm.xml เพิ่มการกำหนดค่าของความสัมพันธ์การเชื่อมโยง
-<หลายชื่อชื่อ = "ชื่อแอตทริบิวต์การเชื่อมโยง"
คอลัมน์ = "ชื่อฟิลด์เชิงสัมพันธ์"
-
ข. การดำเนินการ:
<ชื่อหลายต่อหนึ่ง = "บัญชี"
คอลัมน์ = "account_id"
-
4) ตัวอย่างรหัส
เป็นที่รู้จัก:
-บัญชีทรัพย์สินที่เชื่อมโยงกัน
-บัญชีฟิลด์ที่เชื่อมโยงกัน _id
-บัญชี-> บัญชีชื่อตารางรหัสคีย์หลักรหัส
<span style = "ตัวอักษรขนาด: 14px;"> โมฆะสาธารณะ testfind () {เซสชันเซสชัน = hibernateutil.getSession (); บริการ s = (บริการ) เซสชัน (service.class, 2002); System.out.println ("---- แสดงข้อมูลบัญชีธุรกิจ ----"); System.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); System.out.println ("--- แสดงข้อมูลบัญชีที่เกี่ยวข้อง ---"); System.out.println (s.getAccount (). getId () + "" + s.getAccount (). getRealName ()); } </span>*4. การดำเนินงานที่เกี่ยวข้อง
1) คำถามที่เกี่ยวข้อง
หากคุณต้องการใช้คำสั่ง SQL เพื่อยกตัวอย่างวัตถุปัจจุบันและแอตทริบิวต์ที่เกี่ยวข้องคุณสามารถใช้วิธีการต่อไปนี้:
. (ไม่แนะนำ) แก้ไขการแมปแอตทริบิวต์ที่เกี่ยวข้องใน HBM.XML
คุณลักษณะขี้เกียจ:
จริงหมายความว่าเปิดใช้งานการโหลดขี้เกียจ
เท็จหมายถึงการปิดการโหลดขี้เกียจ
คุณลักษณะดึงข้อมูล:
เข้าร่วมหมายความว่าวิธีการเชื่อมต่อใช้เพื่อสอบถามกับวัตถุหลัก ในเวลานี้ lazy = "false" ไม่ถูกต้อง;
เลือก (ค่าเริ่มต้น) หมายถึงการส่งข้อมูลที่เกี่ยวข้องแบบสอบถาม SQL แยกกัน
ข. (แนะนำ) ผ่าน HQL และเข้าร่วม Fetch Syntax
-จากบัญชีการเข้าร่วม fetch A.Services โดยที่ A.ID =?
ความหมาย: เมื่อตรวจสอบวัตถุบัญชีบริการคุณลักษณะที่เกี่ยวข้องกับบริการจะพบกันโดยใช้การเชื่อมต่อตาราง
-จากบริการ s เข้าร่วม fetch s.count ที่ไหน s.id =?
ความหมาย: เมื่อตรวจสอบวัตถุบริการข้อมูลบัญชีแอตทริบิวต์ที่เกี่ยวข้องบัญชีจะพบร่วมกันโดยใช้การเชื่อมต่อตาราง
-จากบริการ s เข้าร่วม fetch s.cacting ที่ s.account.id =?
สังเกต:
- วัตถุและคุณสมบัติถูกเขียนใน HQL
-การเข้าร่วมการดึงไม่มีในประโยคหลังจากนั้นและการดึงข้อมูลเป็นแอตทริบิวต์ที่เกี่ยวข้อง
-Query.setInteger เพื่อตั้งค่าพารามิเตอร์จำนวนเต็มและตัวห้อยเริ่มต้นจาก 0
-หากเป็นที่ชัดเจนว่า HQL จะส่งคืนหนึ่งระเบียนคุณสามารถใช้วิธี query.uniqueresult () เพื่อส่งคืนบันทึกที่ไม่ซ้ำกัน
ค. รหัสตัวอย่าง (เขียนรหัสสอบถามการเชื่อมโยงแบบหนึ่งถึงหลายครั้งข้างต้น)
<span style = "ตัวอักษรขนาด: 14px;"> โมฆะสาธารณะ testfind () {เซสชันเซสชัน = hibernateutil.getSession (); // บัญชี A = (บัญชี) เซสชันโหลด (บัญชี. class, 1010); String HQL = "จากบัญชี A เข้าร่วม fetch A.Services โดยที่ A.ID =?"; Query Query = session.createquery (HQL); query.setInteger (0, 1010); //? เริ่มต้นจาก 0 บัญชี A = (บัญชี) query.uniqueresult (); // แบบสอบถามบรรทัดเดียวสามารถใช้ System.out.println ("--- ข้อมูลบัญชีแสดง ----"); System.out.println (A.getId () + "" + A.getRealName () + "" + A.GetIdCardno ()); System.out.println ("--- แสดงบัญชีธุรกิจภายใต้บัญชีปัจจุบัน ----"); ตั้งค่า <services> services = a.getServices (); สำหรับ (บริการ s: บริการ) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } system.out.println (a.toString ()); } </span> 2) การเพิ่มการเพิ่มและการดัดแปลงแบบเรียงซ้อน
. เมื่อตารางมีความสัมพันธ์เกี่ยวกับการเชื่อมโยงไฮเบอร์เนตไม่เพียง แต่ให้ฟังก์ชั่นของการสืบค้นสมาคมเท่านั้น แต่ยังมีความสามารถในการเพิ่มแก้ไขและลบข้อมูลในตารางการเชื่อมโยง ความสามารถนี้เรียกว่าการดำเนินการเรียงซ้อน
ข. วิธีการดำเนินการแบบเรียงซ้อน
คุณต้องเพิ่มน้ำตกแอตทริบิวต์ในตำแหน่งที่ตั้งค่าแอตทริบิวต์ที่เกี่ยวข้อง
-ไม่มี: ไม่รองรับการเรียงซ้อนกันตามค่าเริ่มต้น
-การอัปเดตแบบประหยัด: รองรับการเพิ่มและอัปเดต
-Delete: รองรับการลบแบบเรียงซ้อน
-ทั้งหมด: รองรับการเพิ่มการอัปเดตและการลบ
ค. คำอธิบาย
โดยปกติจะมีความสัมพันธ์บนโต๊ะแบบ 1 ถึงหลายคน ด้านหนึ่งของ 1 เป็นตารางหลักและอีกด้านหนึ่งของ 1 คือตารางทาส บ่อยครั้งที่จำเป็นต้องเพิ่มอัปเดตและลบข้อมูลตารางทาสเมื่อเพิ่มอัปเดตและลบตารางหลัก ตัวอย่างเช่น: เมื่อลบบัญชีคุณต้องลบข้อมูลของบัญชีธุรกิจด้วยกัน
3) การลบน้ำตก
. SET CASCADE = "DELETE" หรือ CASCADE = "ทั้งหมด" เพื่อรองรับการลบน้ำตก
ข. โดยทั่วไปจำเป็นต้องเพิ่มแอตทริบิวต์ inverse = "true" ที่แท็กชุดของ 1
ค. Session.delete (OBJ); OBJ จำเป็นต้องเป็นวัตถุถาวรไม่สามารถใหม่ได้และจำเป็นต้องโหลด/ได้รับการเรียกคืน
d. วิธีการลบแบทช์:
Cascading DELETE ใช้คำสั่ง N+1 ลบเพื่อล้างข้อมูลที่เกี่ยวข้องของตารางหลักและตารางคีย์ต่างประเทศ
หากเป็นการ ลบแบบแบทช์ จะไม่แนะนำการลบแบบเรียงซ้อน ขอแนะนำให้ใช้ HQL เพื่อเขียนคำสั่งลบลบ
ลบออกจากบริการที่ account.id =? // ลบข้อมูลทั้งหมดของ account.id =? ในตารางบริการ (ประโยคนี้แทนที่ n ลบงบในการดำเนินการเรียงซ้อน)
ลบออกจากบัญชีที่ id =?
4) รายละเอียดแอตทริบิวต์ผกผัน (ความเข้าใจ) ที่นี่
ไม่ว่าจะเป็นผู้ควบคุมการบำรุงรักษาความสัมพันธ์ นั่นคือโดยค่าเริ่มต้นความสัมพันธ์ระหว่างบัญชีและวัตถุบริการได้รับการดูแลโดยทั้งสองฝ่าย หมายความว่าเมื่อทำการดำเนินการเรียงซ้อนในบัญชีหรือวัตถุบริการคุณจะต้องดำเนินการคำสั่ง UPDATE เพื่อตั้งค่าฟิลด์ที่เกี่ยวข้องกับ ID เดียวกัน หากคุณต้องการยกเลิกงานบำรุงรักษาความสัมพันธ์ของฝ่ายใดฝ่ายหนึ่งคุณสามารถเพิ่มการตั้งค่า Inverse = "True" ในส่วนแอตทริบิวต์ที่เกี่ยวข้องซึ่งสามารถหลีกเลี่ยงการดำเนินการของคำสั่ง UPDATE
จริง: ส่งมอบการควบคุมวัตถุปัจจุบันจะไม่รับผิดชอบในการรักษาความสัมพันธ์ระหว่างสองตาราง
เท็จ: การควบคุมไม่ได้ส่งมอบวัตถุปัจจุบันจะต้องรับผิดชอบในการรักษาความสัมพันธ์ระหว่างสองตาราง
เคล็ดลับ: มันมักจะถูกตั้งค่าเป็น inverse = "true" สำหรับฝ่ายหนึ่ง (เช่นชิ้นส่วนการแมป <หนึ่งต่อหลายครั้ง) เป็นค่าผกผัน = "จริง" เพื่อให้สามารถหลีกเลี่ยงคำสั่งอัปเดตการอัปเดตจำนวนมากเมื่อดำเนินการเรียงซ้อนในฝ่ายเดียว
*5. สมาคมหลายถึงหลายคน
ตัวอย่าง: admin admin_info และบทบาท role_info มีความสัมพันธ์แบบหลายต่อหลาย ฉันหวังว่าเมื่อสอบถามผู้ดูแลระบบเขาสามารถสอบถามบทบาทที่เกี่ยวข้องของเขาได้ เมื่อออกแบบฐานข้อมูลจำเป็นต้องใช้ 3 ตารางเพื่อแสดง
admin_info (ผู้ดูแลระบบ)
admin_role (ความสัมพันธ์ระหว่างผู้ดูแลระบบและบทบาท)
บทบาท (บทบาท)
1) ฟิลด์ความสัมพันธ์
ฟิลด์ความสัมพันธ์อยู่ในตารางกลางของพวกเขา admin_role
admin_id = admin_info.id
role_id = role_info.id
2) ผนวกแอตทริบิวต์ที่เกี่ยวข้องผนวกแอตทริบิวต์ที่เกี่ยวข้องกับบทบาทไปยังคลาสเอนทิตีของผู้ดูแลระบบ
ตั้งค่า <loes> บทบาท
3) ผนวกการกำหนดค่าการแมปการเชื่อมโยงใน admin.hbm.xml
-syntax <set name = "ชื่อแอตทริบิวต์การเชื่อมโยง" table = "ชื่อตารางกลาง"> <คีย์คอลัมน์ = "ชื่อฟิลด์ที่เกี่ยวข้องของผู้ดูแลระบบ"/> <หลายคอลัมน์หลายคอลัมน์ = "ชื่อฟิลด์ที่เกี่ยวข้องของผู้ดูแลระบบของผู้ดูแล
4) การดำเนินการเรียงซ้อน
Cascade หมายถึงการสนับสนุนการดำเนินงานของน้ำตกและตารางทำงานในอีกด้านหนึ่งแทนที่จะเป็นตัวแทนของตารางการดำเนินงานระดับกลาง สำหรับการบำรุงรักษาตารางกลางไม่จำเป็นต้องเขียนแอตทริบิวต์ Cascade
5) ผกผัน
โดยทั่วไปแล้วความสัมพันธ์แบบหลายต่อหลายคนไม่จำเป็นต้องเขียนแบบผกผัน = "จริง" เหตุผลก็คือเมื่อฝ่ายอื่นแทรกข้อมูลอาจไม่มีข้อมูลในตารางกลางและบุคคลปัจจุบันต้องรักษาไว้ ดังนั้นจึงไม่สามารถเขียนแบบผกผัน = "จริง" ได้ มิฉะนั้นทั้งสองฝ่ายจะไม่รักษาความสัมพันธ์นี้และมีปัญหากับข้อมูล
6) ตัวอย่างรหัส Java
<span style = "ตัวอักษรขนาด: 14px;"> // ลบบทบาท @test โมฆะสาธารณะ testDeleterole () {เซสชันเซสชัน = hibernateutil.getSession (); ธุรกรรม tx = session.beginTransaction (); ลอง {admin a = (admin) session.load (admin.class, 1); บทบาท r1 = (บทบาท) เซสชันโหลด (role.class, 1); A.getRoles (). ลบ (R1); session.update (a); tx.commit (); } catch (hibernateException e) {e.printStackTrace (); tx.rollback (); } ในที่สุด {session.close (); }} // ต่อไปบทบาท @Test โมฆะสาธารณะ testAdDrole () {เซสชันเซสชัน = hibernateUtil.getSession (); ธุรกรรม tx = session.beginTransaction (); ลอง {admin a = (admin) session.load (admin.class, 1); บทบาท r1 = (บทบาท) เซสชันโหลด (role.class, 1); บทบาท r2 = (บทบาท) เซสชันโหลด (role.class, 43); บทบาท r3 = (บทบาท) เซสชันโหลด (role.class, 44); A.getRoles (). เพิ่ม (R1); A.getRoles (). เพิ่ม (R2); A.getRoles (). เพิ่ม (R3); session.update (a); tx.commit (); } catch (hibernateException e) {e.printStackTrace (); tx.rollback (); } ในที่สุด {session.close (); }} @Test โมฆะสาธารณะ testFind () {เซสชันเซสชัน = hibernateUtil.getSession (); ธุรกรรม tx = session.beginTransaction (); ลอง {admin a = (admin) session.load (admin.class, 1); System.out.println ("----- แสดงข้อมูลผู้ดูแลระบบ ----"); System.out.println (A.getId () + "" + A.getName () + "" + A.getTelephone ()); System.out.println ("---- แสดงข้อมูลบทบาทผู้ดูแลระบบ ---"); สำหรับ (บทบาทบทบาท: a.getRoles ()) {system.out.println (role.getName () + ""); } tx.Commit (); } catch (hibernateException e) {e.printStackTrace (); tx.rollback (); } ในที่สุด {session.close (); }} </span>6. สมาคมมรดก
ตัวอย่าง: ค้นหาผลิตภัณฑ์บนเว็บไซต์อีคอมเมิร์ซเช่นการป้อน iPhone เพื่อค้นหา ผลการค้นหาอาจรวมถึงข้อมูลผลิตภัณฑ์ที่เกี่ยวข้องกับโทรศัพท์มือถือฟิล์มโทรศัพท์มือถือเคสโทรศัพท์มือถือเครื่องชาร์จหูฟัง ฯลฯ ฟังก์ชั่นนี้สามารถแสดงได้ด้วยความสัมพันธ์แบบหนึ่งต่อหนึ่งพิเศษเมื่อออกแบบตาราง นั่นคือคุณลักษณะทั่วไปของผลิตภัณฑ์ทั้งหมดจะถูกสกัดลงในผลิตภัณฑ์ตารางทั่วไป เฉพาะตารางผลิตภัณฑ์เฉพาะเท่านั้นที่เก็บไว้ในตารางผลิตภัณฑ์เฉพาะดังนั้นตารางผลิตภัณฑ์เฉพาะและตารางผลิตภัณฑ์มีความสัมพันธ์แบบหนึ่งต่อหนึ่ง เมื่อค้นหาคุณสามารถค้นหาตารางผลิตภัณฑ์เท่านั้นและคุณสามารถค้นหาข้อมูลที่เกี่ยวข้องได้
-ผลิตภัณฑ์ตารางข้อมูลทั่วไป (รหัส, ชื่อ, ราคา, DESC)
-หนังสือรายการผลิตภัณฑ์สินค้า (ID, Authod, สำนักพิมพ์, คำ)
-ฉันหวังว่าเมื่อใช้งานตารางหนังสือฉันสามารถรักษาฟิลด์ทั่วไปไว้ในตารางผลิตภัณฑ์โดยอัตโนมัติ
1) ความสัมพันธ์ที่ชัดเจน
หนังสือและผลิตภัณฑ์มีความสัมพันธ์แบบตัวต่อตัว วัตถุประสงค์ของความสัมพันธ์นี้คือการใช้ฟิลด์ซ้ำในตารางผลิตภัณฑ์เช่นความสัมพันธ์การสืบทอด
2) คลาสเอนทิตี
หนังสือขยายผลิตภัณฑ์
3) ความสัมพันธ์ที่เกี่ยวข้องสะท้อนให้เห็นในไฟล์การกำหนดค่า
-ประเภทหลักสอดคล้องกับวิธีการเขียนไฟล์กำหนดค่าดั้งเดิม
-Subtypes มีลักษณะพิเศษ
<เข้าร่วมชื่อชื่อ = "ชื่อชื่อ" ตาราง = "ชื่อตาราง" ขยาย = "ชื่อคลาสแม่"> <คีย์คอลัมน์ = "ชื่อฟิลด์เชื่อมโยง"/> <ชื่อคุณสมบัติ = "" type = "" คอลัมน์ = ""/> ...
4) ในความสัมพันธ์การสืบทอดเนื่องจากทั้งสองตารางมีความสัมพันธ์คล้ายกับของผู้ปกครองและ เด็กข้อมูลในตารางหลักจะต้องอ้างอิงในตารางลูก ไม่มีกรณีของการไม่อ้างอิงนั่นคือตารางหลักจะต้องได้รับการดูแลในขณะที่รักษาตารางลูก ดังนั้นนี่เป็นสถานการณ์ที่แน่นอนดังนั้นคุณไม่จำเป็นต้องเขียนน้ำตกหรือผกผัน
5) หมวดหมู่คำอธิบาย (เข้าใจ)
<Onined-SubClass> ฐานข้อมูลมีตารางคลาสแม่และตารางคลาสเด็ก
<ยูเนี่ยน-subclass> ฐานข้อมูลมีตาราง subclass และไม่มีตารางคลาสแม่ (ตาราง subclass มีฟิลด์ตารางคลาสแม่แล้วไม่มีตารางคลาสแม่ แต่มีวัตถุเอนทิตีคลาสแม่)
<class> ฐานข้อมูลมีคลาสหลักและคลาสเด็กและใช้ตาราง (การออกแบบนั้นยุ่งเหยิงนั่นคือไม่มีการแยกตารางและไม่ค่อยได้ใช้)
*7. แบบสอบถามไฮเบอร์เนต
1) *Query HQL (ภาษาสืบค้นไฮเบอร์เนต)
มันเป็นของคำสั่งสอบถามเชิงวัตถุโดยสอบถาม Pojo ที่แมปโดยไฮเบอร์เนตดังนั้นจึงตระหนักถึงการสอบถามฐานข้อมูล
. ใช้คีย์ที่ไม่ใช่หลักเพื่อทำการสืบค้นตามเงื่อนไข
-พารามิเตอร์เงื่อนไขถึง? ระบุว่า query.setstring (0, "");
-พารามิเตอร์แบบมีเงื่อนไขแสดงโดย: x, query.setstring ("x", "");
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> // ทดสอบเพื่อสืบค้นตามเงื่อนไขโดยคีย์ที่ไม่ใช่พรีเมอร์ @test โมฆะสาธารณะ testFind1 () {String hql = "จากบริการที่บัญชี account.id =? และ unixhost =?"; เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); query.setInteger (0, 1011); query.setstring (1, "192.168.0.23"); รายการ <services> list = query.list (); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } // เทียบเท่ากับ testFind1 โดยใช้ ": ตัวระบุ" แทน @Test โมฆะสาธารณะ testFind2 () {String HQL = "จากบริการที่บัญชี. id =: AID และ unixHost =: host"; เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); query.setInteger ("AID", 1011); query.setstring ("โฮสต์", "192.168.0.23"); รายการ <services> list = query.list (); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } </span> ข. สอบถามคุณลักษณะบางอย่างเท่านั้น
-คอลเลกชันที่ส่งคืนเริ่มต้นที่ห่อหุ้มเป็นวัตถุ []
-บริการใหม่ (id, unixhost, osusername) ห่อหุ้มวัตถุบริการในชุดค่าผสมที่ส่งคืน
สังเกต:
ตัวสร้างที่ต้องการผนวกการตอบกลับในบริการ
อย่าทิ้งคอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> // รับผลลัพธ์บางฟิลด์และใช้วัตถุ [] เพื่อห่อหุ้มข้อมูลโดยค่าเริ่มต้น @Test โมฆะสาธารณะ testFind3 () {String HQL = "เลือก S.ID, S.UNIXHOST, S.OSUSERNAME เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); query.setInteger (0, 1011); รายการ <object []> list = query.list (); สำหรับ (object [] objs: list) {system.out.println (objs [0] + "" + objs [1] + "" + objs [2] + ""); } session.close (); } // เทียบเท่ากับ testFind3 คุณต้องเพิ่มตัวสร้างที่สอดคล้องกัน @Test โมฆะสาธารณะ testFind4 () {String HQL = "เลือกบริการใหม่ (S.ID, S.UNIXHOST, S.OSUSERNAME) จากบริการที่ S.Account.id =?"; เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); query.setInteger (0, 1011); รายการ <services> list = query.list (); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } </span> ค. คำจำกัดความของ HQL อยู่ในไฟล์การกำหนดค่า (เพียงแค่เข้าใจ)
-กำหนด HQL ในไฟล์กำหนดค่าผ่านองค์ประกอบการสืบค้น
-องค์ประกอบคำถามเขียนอยู่เบื้องหลังชั้นเรียน
--session.getNamedQuery (ชื่อ HQL);
รหัสตัวอย่าง: <การสืบค้น/> และ <คลาส/> ถูกวางไว้ใน hbm.xml ในระดับเดียวกัน
<span style = "ตัวอักษรขนาด: 14px;"> <query name = "findall"> <!-รวมฟิลด์ข้อความธรรมดาใน cdata เพื่อป้องกันตัวละครพิเศษ-> <! testFind5 () {เซสชันเซสชัน = hibernateutil.getSession (); // รับคำสั่ง HQL ที่กำหนดไว้ใน <Query> ในการสืบค้นแบบสอบถาม HBM.XML = session.getNamedQuery ("findall"); รายการ <services> list = query.list (); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } </span> d. การสืบค้นการปนเปื้อน
-บันทึกคำถาม
query.setFirstResult ((หน้า 1)*หน้า);
query.setMaxResults (หน้า);
-คำถามจำนวนหน้าทั้งหมด
เลือกนับ (*) จากบริการ
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> // ทดสอบเพจเพจเพจ @Test โมฆะสาธารณะ testFind6 () {int page = 2; String HQL = "จากคำสั่งบริการตาม ID"; เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); // เพิ่มพารามิเตอร์การเพจเพื่อตั้งค่า query.setFirStreSult ((หน้า - 1) * 3); // ตั้งจุดเริ่มต้นสำหรับการคว้าบันทึกเริ่มต้นจาก 0 query.setMaxResults (3); // ตั้งค่าจำนวนสูงสุดของการตั้งค่าการรวบรวมข้อมูล System.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } // เลือกนับ (*) จากบริการ @Test โมฆะสาธารณะ testFind7 () {String hql = "เลือกนับ (*) จากบริการ"; เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); ขนาดยาว = (ยาว) query.uniqueresult (); System.out.println ("จำนวนระเบียนทั้งหมด:" + ขนาด); session.close (); } </span> ก. คำถามที่เกี่ยวข้อง (เพียงจำไว้)
-จากบริการ S, บัญชี A
โดยที่ s.account.id = a.id
-จากบริการเข้าร่วม S.Account A
-เลือก S.Account.realname จาก Service S
สรุป:
ความคล้ายคลึงกันระหว่าง HQL และ SQL :
-รองรับเลือกจากที่ไหนกลุ่มสั่งซื้อตามประโยค
-รองรับการเข้าร่วมการเข้าร่วมซ้ายและการเชื่อมต่ออื่น ๆ
-รองรับ>, <,> =, <=, in, ไม่อยู่ระหว่าง, ระหว่าง, เช่นและเงื่อนไขอื่น ๆ
-ฟังก์ชั่นการจัดกลุ่มสนับสนุนการจัดกลุ่มจำนวน, ผลรวม, สูงสุด, ขั้นต่ำ, AVG
ความแตกต่างระหว่าง HQL และ SQL :
-คำสั่ง HQL เป็นตัวพิมพ์ใหญ่ที่มีความอ่อนไหวเป็นกรณี คำหลักไม่สามารถแยกออกได้
-HQL เขียนชื่อวัตถุและชื่อแอตทริบิวต์ไม่ใช่ชื่อตารางและชื่อฟิลด์
-ไม่ได้รับการสนับสนุนข้อใดข้อหนึ่งในการเข้าร่วม
-ไม่ได้รับการคัดเลือก *
-ฟังก์ชั่นโดเมนไม่ได้รับการสนับสนุนเช่นฟังก์ชันวันที่ to_date (), ฟังก์ชั่นอักขระ to_char () ฯลฯ
2) เคียวรีเกณฑ์ (ไม่ง่ายพอเพียงแค่เข้าใจ)
ใช้ Hibernate API เพื่อสะกด HQL
เกณฑ์ c = session.createCriteria (service.class);
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> // ใช้ API ของไฮเบอร์เนตเพื่อสะกดคำว่า hql @test โมฆะสาธารณะ testfind1 () {เซสชัน = hibernateutil.getSession (); เกณฑ์ c = session.createCriteria (service.class); C.ADD (ข้อ จำกัด และ (ข้อ จำกัด เช่น ("Osusername", "Huang%"), ข้อ จำกัด . eq ("unixhost", "192.168.0.26"))); c.addorder (order.desc ("id")); // ผนวกเรียงลำดับ // c.setfirstresult (arg0); // pagination // c.setMaxResults (arg0); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername () + "" + s.getunixhost ()); } session.close (); } </span> 3) SQL แบบสอบถาม
ช่วยเราโทรหา JDBC โดยตรงเพื่อดำเนินการค้นหา SQL
sqlQuery sqlQuery = session.createsqlQuery (SQL);
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> @Test โมฆะสาธารณะ testFind1 () {String SQL = "SELECT * จากบริการ"; เซสชั่นเซสชัน = hibernateutil.getSession (); sqlQuery sqlQuery = session.createsqlQuery (SQL); sqlQuery.setFirstresult (0); // pagination sqlQuery.setMaxResults (3); // โดยค่าเริ่มต้นอาร์เรย์จะใช้เพื่อห่อหุ้มรายการบันทึก <วัตถุ []> list = sqlQuery.list (); สำหรับ (วัตถุ [] objs: list) {system.out.println (objs [0] + "" + objs [2]); } session.close (); } // เหมือนกับ testFind1 () ระบุเอนทิตีที่ห่อหุ้มบันทึก @Test สาธารณะ void testFind2 () {String SQL = "SELECT * จากบริการ"; เซสชั่นเซสชัน = hibernateutil.getSession (); sqlQuery sqlQuery = session.createsqlQuery (SQL); sqlQuery.setFirstresult (0); // pagination sqlQuery.setMaxResults (3); // ระบุคลาสเอนทิตีที่ห่อหุ้มบันทึก sqlQuery.addentity (service.class); // ห่อหุ้มเร็กคอร์ดด้วยรายการประเภทบริการที่ระบุ <ervice> list = sqlQuery.list (); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername ()); } session.close (); } </span>8. คุณสมบัติขั้นสูงของไฮเบอร์เนต (ความเข้าใจ)
1) แคชระดับ 2
. แคชระดับ 2 (ปิดเริ่มต้น)
-แคชระดับที่สองเป็นแคชระดับเซสชัน factory ซึ่งได้รับการจัดการโดย SessionFactory
-วัตถุแคชยังเป็นวัตถุเอนทิตี
-ข้อมูลที่ถูกจับสามารถใช้ร่วมกันระหว่างเซสชันที่แตกต่างกัน
-สภาพแวดล้อมที่ใช้งานได้: ข้อมูลวัตถุที่ใช้ร่วมกันบ่อยครั้ง ความถี่เล็ก ๆ ของการเปลี่ยนแปลงข้อมูลวัตถุ
ข. ขั้นตอนสำหรับการใช้แคชระดับ 2
-แพ็คเกจแคช-แห้ง ehcache.jar
-ง่าย ๆ ไฟล์การกำหนดค่าแคช ehcache.xml
-ใน hibernate.cfg.xml ตั้งค่าเพื่อเปิดใช้งานแคชรองและตั้งค่าคลาสไดรเวอร์แคช
<span style = "ตัวอักษรขนาด: 14px;"> <!-การใช้แคชระดับ 2-> <property name = "hibernate.cache.use_second_level_cache"> true </property> <!-ระบุคลาสไดรเวอร์ ehcache.jar-> <คุณสมบัติ name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </คุณสมบัติ> </span>
-ตั้งค่าองค์ประกอบในไฟล์การแมปเชิงสัมพันธ์ hbm.xml ของ pojo ที่จะแคช <cache usage = "อ่านอย่างง่าย"/>
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> <span style = "font-size: 14px;"> @test โมฆะสาธารณะ testfind1 () {// สำหรับการสืบค้นแรกใช้เซสชันเซสชัน 1 เซสชัน 1 = hibernateutil.getSession (); บริการ S1 = (บริการ) เซสชั่น 1.get (Service.class, 2002); System.out.println (s1.getosusername () + "" + s1.getunixhost ()); เซสชั่น 1.close (); // การสืบค้นที่สองใช้เซสชัน 2 (หลังจากกำหนดค่าแคชรองทั้งสองข้อความค้นหาไปที่แคชรองเพื่อดึงข้อมูล) // hibernateutil.getSessionFactory () evict (service.class); // หลังจากการลบคุณยังคงสืบค้นสองครั้ง เซสชั่นเซสชัน 2 = hibernateutil.getSession (); บริการ S2 = (บริการ) Session2.get (Service.class, 2002); System.out.println (s2.getosusername () + "" + s2.getunixhost ()); } </span> </span> 2) แคชแบบสอบถาม
. แคชแบบสอบถาม
แคชระดับ 1 และระดับ 2 สามารถแคชวัตถุเดียวเท่านั้น หากคุณพบผลลัพธ์สตริงผลลัพธ์อาร์เรย์หรือรายการรวบรวมคุณสามารถใช้ที่เก็บแคชคิวรี
-มันถือได้ว่าเป็นแคชระดับ 2 พิเศษ
-พื้นที่แคชที่ใช้คือแคชระดับที่สอง
-แคชคือประเภทข้อมูลอื่นที่ไม่ใช่วัตถุเอนทิตี
-พึ่งพาแคชระดับ 2 จะถูกปิดโดยค่าเริ่มต้นและจะต้องเปิดแคชระดับ 2 ก่อนที่จะสามารถใช้งานได้
ข. ใช้ขั้นตอน
-เปิดแคชระดับ 2
-ตั้งค่าแคชแบบคิวรีแบบเปิดใน hibernate.cfg.xml
<span style = "Font-Size: 14px;"> <!-เปิดแคชแบบสอบถาม-> <property name = "hibernate.cache.use_query_cache"> true </property> </span>
ก่อนที่จะสอบถาม -QUARY.LIST (), query.setCacheable (จริง);
ค. สภาพแวดล้อมการใช้งาน
-คำสั่งค้นหาเดียวกันที่ต้องดำเนินการบ่อยครั้ง
-เนื้อหาการสืบค้นตั้งค่าการเปลี่ยนแปลงความถี่เล็ก ๆ
-ไม่มีข้อมูลมากเกินไปในชุดผลลัพธ์ เคล็ดลับ: สำหรับ SQL เดียวกันให้ไปที่ฐานข้อมูลเป็นครั้งแรกในการสอบถามและออกจากแคชหลายครั้งในอนาคต เนื่องจากเนื้อหาของชุดผลลัพธ์ SQL+ ถูกแคช
รหัสตัวอย่าง:
<span style = "ตัวอักษรขนาด: 14px;"> <span style = "font-size: 14px;"> @test public void testfind () {find (); System.out.println ("-------"); หา(); } โมฆะส่วนตัวค้นหา () {String hql = "จากบริการที่ account.id =?"; เซสชั่นเซสชัน = hibernateutil.getSession (); Query Query = session.createquery (HQL); query.setInteger (0, 1011); // เปิดใช้งานการสืบค้นแคชแบบสอบถาม Query.setCacheable (จริง); รายการ <services> list = query.list (); สำหรับ (บริการ s: list) {system.out.println (s.getId () + "" + s.getosusername ()); }} </span> </span>9. ไฮเบอร์เนตล็อคการประมวลผลพร้อมกัน
ตัวอย่างเช่น:
จำลองกลไกการซื้อตั๋ว 12306 โดยสมมติว่าปัจจุบันมีตั๋วตั๋ว (ID, บรรทัด, จำนวน, ตั๋วรถไฟและจำลองสถานการณ์ที่หลายคนซื้อตั๋วในเวลาเดียวกัน
1) ล็อคในแง่ร้าย
-โปรแกรมเป็นแง่ร้ายที่ผู้เข้าชมทุกคนมีปัญหาพร้อมกันดังนั้นข้อมูลแต่ละชิ้นจะถูกล็อค จากนั้นเฉพาะเมื่อผู้เข้าชมปัจจุบันถือล็อคปล่อยล็อคผู้เข้าชมรายถัดไปสามารถเข้าถึงข้อมูลได้ กลไกนี้เรียกว่าล็อคในแง่ร้าย
-นั่นคือคุณต้องล็อคข้อมูลไม่ว่าจะเกิดอะไรขึ้นไม่ว่าข้อมูลจะมีการเกิดขึ้นพร้อมกันหรือไม่
--คุณสมบัติ
ประสิทธิภาพต่ำและความปลอดภัยสูง
--ทำให้สำเร็จ:
รับ (คลาส, id, lockmode.upgrade)
เลือก * จาก EMP สำหรับการอัปเดต
หมายเหตุ: ที่นี่เราใช้ประโยคการอัปเดตที่มาพร้อมกับฐานข้อมูลสำหรับการล็อคไม่ใช่กลไกการล็อคที่คิดค้นโดย Hibernate เอง
2) การล็อคในแง่ดี
-โปรแกรมในแง่ดีว่าผู้เข้าชมทุกคนจะไม่มีปัญหาพร้อมกันดังนั้นจึงไม่เพิ่มล็อค แต่เมื่อข้อมูลได้รับการอัปเดตจะถูกกำหนดว่าเวอร์ชันของข้อมูลมีการเปลี่ยนแปลงหรือไม่ หากมีการเปลี่ยนแปลงหมายความว่ามีการเกิดขึ้นพร้อมกันในช่วงเวลานี้ ดังนั้นจึงมีการรายงานข้อผิดพลาดและการอัปเดตล้มเหลว
-ด้วยความช่วยเหลือของฟิลด์เวอร์ชันเมื่อผู้ใช้คนแรกอัปเดตและส่ง Hibernate จะอัปเดตฟิลด์โดย 1 เพื่อให้ฟิลด์เวอร์ชันวัตถุที่ส่งโดยผู้ใช้ที่ตามมามีขนาดเล็กกว่าในฐานข้อมูลนั่นคือเมื่อพบว่าเวอร์ชันมีการเปลี่ยนแปลงในระหว่างการอัปเดต
-ความสำเร็จอย่างหนึ่งความล้มเหลวอื่น ๆ
--คุณสมบัติ
มีประสิทธิภาพสูงประสบการณ์ผู้ใช้ที่ไม่ดี
--ทำให้สำเร็จ
. คุณต้องผนวกฟิลด์เวอร์ชันเข้ากับตารางเพื่อบันทึกเวอร์ชันของข้อมูล
ข. ผนวกแอตทริบิวต์เวอร์ชันเข้ากับคลาสเอนทิตี
ค. การกำหนดค่าของเวอร์ชันเพิ่มเติมใน hbm.xml <name name = "" type = "" คอลัมน์ = "">
3) วิธีการเลือก
-หากการพร้อมกันมีขนาดใหญ่ควรเลือกล็อคในแง่ดี
-หากการเกิดพร้อมกันมีขนาดเล็กคุณควรเลือกล็อคในแง่ร้าย
ข้างต้นคือการวิเคราะห์ที่ครอบคลุมของการดำเนินงานที่เกี่ยวข้องกับไฮเบอร์เนตการดำเนินการแบบสอบถามคุณสมบัติขั้นสูงและกลไกการประมวลผลพร้อมกันที่แนะนำโดยเครื่องมือแก้ไขให้คุณ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!