บทความนี้อธิบายถึงหลักการและวิธีการใช้งานของการโหลดล่าช้าไฮเบอร์เนต แบ่งปันสำหรับการอ้างอิงของคุณดังนี้:
เพื่อเพิ่มประสิทธิภาพการทำงานของไฮเบอร์เนตคุณสามารถใช้:
เทคโนโลยีการโหลดเวลาแฝงการจัดการกลยุทธ์การรวบรวมข้อมูลและดำเนินการจัดการแคชเพื่อปรับปรุงประสิทธิภาพของไฮเบอร์เนต
1. การโหลดล่าช้า (โหลด)
Lazy Loading เป็นกลไกที่จัดทำโดย Hibernate เพื่อปรับปรุงประสิทธิภาพการดำเนินการของโปรแกรมนั่นคือมันจะถูกสร้างขึ้นเฉพาะเมื่อข้อมูลของวัตถุถูกใช้จริง
กระบวนการโหลดขี้เกียจ: การโหลดล่าช้าทำได้ผ่านกลไกพร็อกซี เมื่อไฮเบอร์เนตได้รับข้อมูลจากวัตถุบางอย่างจากฐานข้อมูลเมื่อได้รับค่าแอตทริบิวต์การรวบรวมของวัตถุหรือเมื่อได้รับวัตถุอื่นที่เกี่ยวข้องกับวัตถุเนื่องจากข้อมูลของวัตถุไม่ได้ใช้ (ยกเว้นตัวระบุ) ไฮเบอร์เนตไม่โหลดข้อมูลจริงจากฐานข้อมูล แอตทริบิวต์ทั้งหมดในวัตถุนี้เป็นค่าเริ่มต้น วัตถุจริงนี้ถูกสร้างขึ้นเฉพาะเมื่อจำเป็นต้องใช้ข้อมูลของวัตถุจริง ๆ และข้อมูลของมันจะถูกโหลดจากฐานข้อมูล
เมื่อวิธีการโหลด () ในเซสชันถูกเรียกให้โหลดเอนทิตี; เมื่อเซสชันโหลดเอนทิตีค่าแอตทริบิวต์การรวบรวมในเอนทิตีจะถูกโหลดด้วยการโหลดล่าช้า เมื่อเซสชันโหลดเอนทิตีวัตถุเอนทิตีอื่น ๆ ที่เอนทิตีเป็นปลายเดี่ยวการโหลดล่าช้าจะถูกใช้สำหรับวัตถุเอนทิตีอื่นที่เกี่ยวข้องกับปลายเดี่ยว
ปิดการโหลดขี้เกียจ: เมื่อโหลดเอนทิตีเดียวคุณสามารถใช้วิธีการรับ ()
สำหรับแอตทริบิวต์การรวบรวมในเอนทิตีคุณสามารถเพิ่มแอตทริบิวต์ lazy = "เท็จ" ในชุดนี้ (<et>, <ag>, <list> …) เมื่อการเชื่อมโยงปลายเดี่ยวของวัตถุเอนทิตีอื่นคุณสามารถกำหนดค่า <หนึ่งต่อหนึ่ง>, <หลายต่อหนึ่ง> เพื่อเพิ่มแอตทริบิวต์ lazy = "เท็จ" ในไฟล์การแมปหมายเหตุ: หนึ่งต่อหนึ่งไม่สามารถ จำกัด ได้ = จริง (คีย์ต่างประเทศจะแสดงในคำสั่ง SQL ที่สร้างขึ้น)
2. ประเภทหลักของการโหลดขี้เกียจใช้ในไฮเบอร์เนตโดยค่าเริ่มต้น:
•การโหลดขี้เกียจใช้เมื่อวิธีการโหลด () ในเซสชันถูกเรียกให้โหลดเอนทิตี
•เมื่อเซสชันโหลดเอนทิตีค่าแอตทริบิวต์การรวบรวมในเอนทิตีนี้จะถูกโหลดด้วยความล่าช้า (หนึ่งถึงหลายคน)
•เมื่อเซสชันโหลดเอนทิตีวัตถุเอนทิตีอื่นที่มีปลายเดี่ยว (แบบหนึ่งต่อหนึ่งหลายต่อหนึ่ง) ที่เกี่ยวข้องกับเอนทิตีจะโหลดขี้เกียจ
•ความแตกต่างระหว่างที่สองและสามคือ: ในกรณีที่สองวิธีที่จะยกเลิกการโหลดการหน่วงเวลาคือการตั้งค่าแอตทริบิวต์การโหลดขี้เกียจ lazy = "เท็จ" หลังจากแท็กชุดของไฟล์การแมปของฝ่ายหนึ่งที่มีแอตทริบิวต์ชุด; ในกรณีที่สามแท็กแบบหลายต่อหนึ่งในไฟล์การแมปของหลายฝ่ายที่มีหลายต่อหนึ่งนั่นคือแท็กแบบหลายต่อหนึ่งถูกตั้งค่า
วัตถุที่สามารถโหลดได้อย่างขี้เกียจคือวัตถุพร็อกซีที่เขียนใหม่ทั้งหมด เมื่อเซสชันที่เกี่ยวข้องไม่ได้ปิดการเข้าถึงคุณสมบัติของวัตถุที่โหลดขี้เกียจเหล่านี้ (พร็อกซี) (ยกเว้น getId และ getClass) ไฮเบอร์เนตจะเริ่มต้นพร็อกซีเหล่านี้หรือใช้ hibernate.initialize (พร็อกซี) เพื่อเริ่มต้นวัตถุพร็อกซี; เมื่อเซสชันที่เกี่ยวข้องถูกปิดข้อยกเว้นจะเกิดขึ้นเพื่อเข้าถึงวัตถุที่โหลดขี้เกียจ
3. กลยุทธ์การรวบรวมข้อมูล (Fetch)
กำหนดค่า "นโยบายการรวบรวมข้อมูล" เพื่อส่งผลโดยตรงต่อเอฟเฟกต์การสืบค้นของวิธีการรับ () และโหลด () ของเซสชัน
กลยุทธ์การรวบรวมข้อมูลเกี่ยวกับการเชื่อมโยงแบบปลายเดี่ยว <หลายต่อหนึ่ง> <หนึ่งต่อ _one>:
คุณสามารถเพิ่มแอตทริบิวต์การดึงข้อมูลลงในองค์ประกอบการแมปที่เกี่ยวข้องแบบปลายเดี่ยว เลือก: การโหลดล่าช้า; เข้าร่วม: ใช้การเชื่อมต่อภายในในคำสั่ง SELECT เดียวกันเพื่อรับข้อมูลของวัตถุและข้อมูลของวัตถุที่เกี่ยวข้อง ในเวลานี้การโหลดล่าช้าของวัตถุที่เกี่ยวข้องไม่ถูกต้อง
กลยุทธ์การรวบรวมข้อมูลเกี่ยวกับคุณสมบัติการรวบรวม :
เลือก: การโหลดล่าช้า; เข้าร่วม: ใช้การเข้าร่วมภายในในคำสั่ง SELECT เดียวกันเพื่อให้ได้ชุดสมาคมของอีกฝ่าย ในเวลานี้ขี้เกียจในชุดที่เกี่ยวข้องจะไม่ถูกต้อง Subselect: ส่งคำสั่งค้นหาอื่นหรือคำถามย่อยเพื่อรวบรวมข้อมูล กลยุทธ์นี้ยังใช้งานได้สำหรับการสืบค้น HQL
4. การวิเคราะห์เคสโหลดขี้เกียจ
กรณีที่ 1: เอนทิตีเดียวเรียกใช้วิธีการโหลด () เพื่อยกเลิกการโหลดขี้เกียจ
แพ็คเกจ com.hbsi.test; นำเข้า org.hibernate.session; นำเข้า org.junit.test; นำเข้า com.hbsi.domain.user; นำเข้า com.hbsi.utils.hibernateutil; publicclass testlazy {// test test () วิธีการ () จะดำเนินการ SQL hibernateutil.getSession (); ผู้ใช้ผู้ใช้ = (ผู้ใช้) เซสชัน Session.get (user.class, 1); // system.out.println (user.getName ()); hibernateutil.close (); // หมายเหตุที่นี่: แม้ว่าเซสชันจะปิดและผู้ใช้อยู่ในสถานะที่มีการจัดการ นี่เป็นเพราะแม้ว่ามันจะอยู่ในสถานะที่มีการจัดการ แต่วัตถุนี้เป็นวัตถุที่มีค่าแอตทริบิวต์และไม่ลบ แต่แยกเฉพาะช่องสำหรับการจัดการกับฐานข้อมูล System.out.println (user.getName ());} // วิธี testload (); อย่าเรียกใช้คำสั่ง SQL และดำเนินการเฉพาะ @TestPublicVoid testload () {เซสชันเซสชัน = hibernateUtil.getSession (); ผู้ใช้ผู้ใช้ = (ผู้ใช้) เซสชันการโหลด (user.class, 1); // รหัสเอาต์พุตที่นี่จะไม่เรียกใช้คำสั่ง SQL มันจะได้รับ ID โดยตรงจาก ID ที่คุณผ่านด้านบน มันไม่ได้ค้นหาจากฐานข้อมูลดังนั้นคำสั่ง SQL System.out.println (user.getId ()); // ชื่อเอาต์พุตแตกต่างกัน ในเวลานี้วัตถุพร็อกซีจะถูกสร้างอินสแตนซ์จริง นี่คือวัตถุพร็อกซีที่มีแอตทริบิวต์ชื่อ ในเวลานี้แม้ว่าคุณจะปิดเซสชันคุณยังสามารถรับชื่อผ่านวัตถุนี้ได้ หากคุณแสดงความคิดเห็นประโยคนี้นั่นคือวัตถุพร็อกซีจะไม่อินสแตนซ์วัตถุพร็อกซีจากนั้นเรียกใช้แอตทริบิวต์ชื่อเอาต์พุตหลังจากปิดเซสชันจะมีการรายงานข้อผิดพลาด: ไม่สามารถเริ่มต้นพร็อกซี // system.out.println (user.getName ()); hibernateutil.close ();สถานการณ์ที่ 2: ยกเลิกการโหลดขี้เกียจในชุด
ทดสอบว่า Lazy Load ในแอตทริบิวต์การรวบรวมถูกตั้งค่าเป็น FALSE ในไฟล์การแมปมันจะถูกนำมารวมกับข้อมูลในตารางคำสั่งซื้อนั่นคือสองคำสั่งเลือก
@TestPublicVoid find () {เซสชันเซสชัน = hibernateutil.getSession (); ลูกค้า cus = (ลูกค้า) เซสชัน (ลูกค้า. class, 3); system.out.println (cus.getcname ()); // ใช้วิธีการต่อไปนี้ หากใช้การโหลดแบบขี้เกียจคำสั่ง SQL สองใบจะถูกส่งออกก่อนและผลลัพธ์ผลลัพธ์คือ // วิธีการไม่สามารถถูกล่ามโซ่ได้โดยตรงที่นี่เพื่อส่งออก cus.getord (). getOname (); เพราะ cus.getord () ส่งคืนชุดชุด <คำสั่งซื้อ> คำสั่งซื้อ = cus.getord (); system.err.println (order.size ()); hibernateutil.close ();}วิธีที่ 3: <หนึ่งต่อหนึ่ง>, <หลายต่อหนึ่ง> ยกเลิกการโหลดขี้เกียจ
@TestPublicVoid ค้นหา () {// โดยค่าเริ่มต้นการโหลดขี้เกียจนั่นคือเอาต์พุตหนึ่งด้วยคำสั่ง SQL; หากการโหลดการหน่วงเวลาถูกตั้งค่าเป็นเท็จและเอาต์พุตคำสั่ง SQL สองใบจะพบข้อมูลลูกค้าที่ไม่พึงประสงค์ เซสชันเซสชัน = hibernateutil.getSession (); คำสั่ง ORD = (คำสั่งซื้อ) เซสชัน (order.class, 3); system.out.println (ord.getOname ()); hibernateutil.close ();};};ฉันหวังว่าคำอธิบายในบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม Java ของทุกคนตามกรอบการทำงานของไฮเบอร์เนต