การโหลดขี้เกียจใน Java คืออะไร ฉันไม่เข้าใจกระบวนการ ใครช่วยให้ฉันเข้าใจกระบวนการขี้เกียจโหลดได้หรือไม่
การโหลดขี้เกียจใน Java คืออะไร ฉันไม่เข้าใจกระบวนการ ใครช่วยให้ฉันเข้าใจกระบวนการขี้เกียจโหลดได้หรือไม่
คำตอบ:
สมมติว่าคุณมีผู้ปกครองและผู้ปกครองนั้นมีคอลเลกชันของเด็ก ๆ ตอนนี้ไฮเบอร์เนตสามารถ "lazy-load" children ได้ซึ่งหมายความว่าไม่ได้โหลด children ทั้งหมดเมื่อโหลดพาเรนต์ แต่จะโหลดเมื่อมีการร้องขอ คุณสามารถร้องขอสิ่งนี้ได้อย่างชัดเจนหรือและนี่เป็นเรื่องธรรมดามากที่ไฮเบอร์เนตจะโหลดโดยอัตโนมัติเมื่อคุณพยายามเข้าถึงเด็ก
การโหลดขี้เกียจสามารถช่วยปรับปรุงประสิทธิภาพได้อย่างมีนัยสำคัญเนื่องจากบ่อยครั้งที่คุณไม่ต้องการใช้ลูกดังนั้นจึงไม่โหลด
นอกจากนี้ระวังปัญหา n + 1 ด้วย ไฮเบอร์เนตจะไม่โหลดเด็กทั้งหมดเมื่อคุณเข้าถึงคอลเลกชัน แต่จะโหลดเด็กแต่ละคนแยกกัน เมื่อวนซ้ำคอลเลกชันสิ่งนี้จะทำให้แบบสอบถามสำหรับเด็กทุกคน เพื่อหลีกเลี่ยงปัญหานี้คุณสามารถหลอกให้จำศีลในการโหลดเด็กทุกคนพร้อมกันเช่นโดยการเรียก parent.getChildren (). size ()
"โหลดขี้เกียจ" หมายความว่าองค์กรจะถูกโหลดเพียงเมื่อคุณจริงเข้าถึงนิติบุคคลสำหรับครั้งแรกเวลา
รูปแบบที่เป็นเช่นนี้
public Entity getEntity() {
if (entity == null) {
entity = loadEntity();
}
return entity;
}
นี้ช่วยประหยัดค่าใช้จ่ายของการพรีโหลด / กำลังเติมล่วงหน้าทุกหน่วยงานในชุดข้อมูลที่มีขนาดใหญ่ก่อนในขณะที่คุณหลังจากทั้งหมดจริงไม่จำเป็นต้องทั้งหมดของพวกเขา
ใน Hibernate คุณสามารถกำหนดค่าให้โหลดชุดเอนทิตีชายน์อย่างเกียจคร้านได้ จริงโหลดขี้เกียจจะทำแล้วภายในวิธีการที่PersistentSet
ซึ่งใช้ Hibernate "ภายใต้หมวก" Set
การที่จะกำหนดให้คอลเลกชันของหน่วยงานเป็น
เช่น
public class Parent {
private Set<Child> children;
public Set<Child> getChildren() {
return children;
}
}
.
public void doSomething() {
Set<Child> children = parent.getChildren(); // Still contains nothing.
// Whenever you call one of the following (indirectly),
// Hibernate will start to actually load and fill the set.
children.size();
children.iterator();
}
Martin Fowler กำหนดรูปแบบLazy Loadในรูปแบบของสถาปัตยกรรมแอปพลิเคชันองค์กรเช่น:
วัตถุที่ไม่มีข้อมูลทั้งหมดที่คุณต้องการ แต่รู้วิธีที่จะได้รับ
ดังนั้นเมื่อโหลดวัตถุที่กำหนดความคิดคือไม่อยากโหลดวัตถุที่เกี่ยวข้องที่คุณไม่สามารถใช้งานได้ทันทีเพื่อประหยัดต้นทุนประสิทธิภาพที่เกี่ยวข้อง แต่วัตถุที่เกี่ยวข้องจะถูกโหลดเมื่อใช้งานเท่านั้น
นี่ไม่ใช่รูปแบบเฉพาะสำหรับการเข้าถึงข้อมูลและไฮเบอร์เนต แต่มีประโยชน์อย่างยิ่งในฟิลด์ดังกล่าวและไฮเบอร์เนตรองรับการโหลดการเชื่อมโยงแบบหนึ่งต่อหลายและการเชื่อมโยงแบบจุดเดียว (ขี้เกียจ) และแบบหนึ่งต่อหนึ่ง ภายใต้เงื่อนไขบางประการ รายละเอียดเพิ่มเติมในบทที่ 19ของเอกสารอ้างอิงอ้างอิง Hibernate 3.0
Bydefault lazy loading เป็น true.Lazy loading หมายถึงเมื่อดำเนินการแบบสอบถามแบบใช้เลือกข้อมูลนั้นจะไม่เกิดผลกับฐานข้อมูล มันจะรอฟังก์ชั่น getter เช่นเมื่อเราต้องการมันจะดึงข้อมูลจากดาต้าเบส ตัวอย่างเช่นคุณเป็นผู้ปกครองที่มีเด็กที่มีของเล่นมากมาย แต่ปัญหาในปัจจุบันคือเมื่อใดก็ตามที่คุณเรียกเขาว่า (เราสมมติว่าคุณมีเด็กผู้ชาย) เขามาหาคุณพร้อมกับของเล่นทั้งหมดของเขาเช่นกัน ตอนนี้เป็นปัญหาเนื่องจากคุณไม่ต้องการให้เขาอุ้มของเล่นของเขาตลอดเวลา ดังนั้นการเป็นผู้ปกครองเหตุผลคุณไปข้างหน้าและกำหนดของเล่นของเด็กเป็นขี้เกียจ ตอนนี้เมื่อใดก็ตามที่คุณโทรหาเขาเขาจะมาหาคุณโดยไม่มีของเล่นของเขา
การดึงข้อมูล Lazy ตัดสินใจว่าจะโหลดวัตถุลูกขณะโหลดวัตถุแม่หรือไม่ คุณต้องทำการตั้งค่าไฟล์การจำศีลตามลำดับของคลาสพาเรนต์
Lazy = true
(หมายถึงไม่ให้โหลดลูก) โดยค่าเริ่มต้นการโหลดวัตถุวัตถุลูกนั้นจะเป็นความจริง
สิ่งนี้ทำให้แน่ใจว่าวัตถุลูกไม่ได้ถูกโหลดเว้นแต่พวกมันจะถูกเรียกอย่างชัดเจนในแอพพลิเคชั่นโดยการเรียกgetChild()
วิธีการกับผู้ปกครองในกรณีนี้ไฮเบอร์เนตจะเรียกการเรียกฐานข้อมูลใหม่เพื่อโหลดเด็กเมื่อgetChild()
ถูกเรียกใช้บนวัตถุแม่
แต่ในบางกรณีคุณจำเป็นต้องโหลดวัตถุลูกเมื่อโหลดแม่ เพียงแค่ทำให้ lazy = false และ hibernate จะโหลดลูกเมื่อแม่ถูกโหลดจากฐานข้อมูล
ตัวอย่าง: ถ้าคุณมีตาราง พนักงานจับคู่กับวัตถุของพนักงานและมีชุดของวัตถุที่อยู่ คลาสหลัก: คลาสพนักงาน, คลาสย่อย: คลาสที่อยู่
public class Employee {
private Set address = new HashSet(); // contains set of child Address objects
public Set getAddress () {
return address;
}
public void setAddresss(Set address) {
this. address = address;
}
}
ในไฟล์ Employee.hbm.xml
<set name="address" inverse="true" cascade="delete" lazy="false">
<key column="a_id" />
<one-to-many class="beans Address"/>
</set>
ในการกำหนดค่าข้างต้น ถ้าlazy="false"
: - เมื่อคุณโหลดออบเจ็กต์พนักงานในขณะนั้นที่อยู่ออบเจ็กต์ลูกจะถูกโหลดและตั้งค่าเป็นเมธอด setAddresss () ถ้าคุณโทร employee.getAdress () ดังนั้นข้อมูลที่โหลดกลับมาจะไม่มีการเรียกฐานข้อมูลใหม่
ถ้าlazy="true"
: - นี่คือการกำหนดค่าเริ่มต้น ถ้าคุณไม่พูดถึงก็จำศีลพิจารณาว่าขี้เกียจ = จริง เมื่อคุณโหลดวัตถุพนักงานที่วัตถุลูกเวลาที่อยู่ไม่ได้โหลด คุณต้องมีการโทรพิเศษไปยังฐานข้อมูลเพื่อรับวัตถุที่อยู่ ถ้าคุณเรียกใช้employee.getAdress()
แบบสอบถามฐานข้อมูลเวลานั้นจะยิงและส่งคืนผลลัพธ์ การเรียกฐานข้อมูลใหม่
ในภาษาของคนธรรมดามันเหมือนกับว่าคุณกำลังทำเค้กและคุณจะต้องใช้ส่วนผสม 5-10 อย่างจากตู้เย็น คุณมีสองตัวเลือกรับส่วนผสมทั้งหมดจากตู้เย็นและวางไว้บนแพลตฟอร์มห้องครัวของคุณหรือนำรายการที่คุณต้องการเมื่อคุณต้องการ
ในทำนองเดียวกันในการโหลดกระตือรือร้นคุณดึงข้อมูลทั้งหมดเกี่ยวกับถั่วและชั้นเรียนที่เกี่ยวข้อง (ไม่ใช่ลูกหรือเป็นความสัมพันธ์ แต่มีความสัมพันธ์เช่นเค้กมีแป้งมีนมมีครีม ฯลฯ ) และในกรณีที่โหลดขี้เกียจก่อน คุณนำเฉพาะตัวบ่งชี้และค่านิยมที่มาจากตารางเดียวกัน (ส่วนผสมที่จำเป็นซึ่งคุณต้องใช้ในชามเค้กก่อน) ข้อมูลทั้งหมดที่มาจากตารางอื่น ๆ จะถูกดึงมาเป็นและเมื่อจำเป็น / ใช้
กำลังโหลดขี้เกียจ? หมายความว่าระเบียนของเด็กจะไม่ถูกดึงออกมาทันที แต่โดยอัตโนมัติทันทีที่คุณพยายามเข้าถึง
การโหลดแบบ Lazy ช่วยให้คุณเลื่อนการดึงการเชื่อมโยงหรือควบคุมการดึงข้อมูลกลยุทธ์ได้ดีขึ้น
เมื่อคุณใช้การโหลด EAGER คุณกำหนดแผนการดึงข้อมูลทั่วโลกซึ่งไม่สามารถเขียนทับได้ในเวลาสืบค้นซึ่งหมายความว่าคุณ จำกัด การตัดสินใจของคุณในขณะที่ออกแบบโมเดลเอนทิตีของคุณ การดึงข้อมูลของ EAGER เป็นกลิ่นรหัสเนื่องจากกลยุทธ์การดึงข้อมูลเป็นนโยบายเวลาสืบค้นและอาจแตกต่างจากกรณีการใช้งานทางธุรกิจไปยังอีกกรณีหนึ่ง
กลยุทธ์การดึงข้อมูลเป็นสิ่งสำคัญมากในขณะที่กำลังนำเกินไปกระตือรือร้นมากอาจทำให้เกิดปัญหาประสิทธิภาพการทำงานที่เกี่ยวข้องอย่างจริงจัง
การตั้งค่า Lazy ตัดสินใจว่าจะโหลดวัตถุลูกในขณะที่โหลดวัตถุหลักหรือไม่คุณต้องทำการตั้งค่าไฟล์การทำแผนที่จำศีลตามลำดับของคลาสผู้ปกครอง Lazy = true (หมายถึงไม่โหลดเด็ก) โดยค่าเริ่มต้นการโหลดวัตถุวัตถุลูกนั้นเป็นจริง . สิ่งนี้ทำให้แน่ใจว่าวัตถุลูกไม่ได้ถูกโหลดเว้นแต่พวกมันจะถูกเรียกอย่างชัดเจนในแอพพลิเคชั่นโดยเรียกเมธอด getChild () บนพาเรนต์ในกรณีนี้ไฮเบอร์เนตจะเรียกใช้ฐานข้อมูลใหม่เพื่อโหลดเด็กเมื่อ getChild () วัตถุ แต่ในบางกรณีคุณจำเป็นต้องโหลดวัตถุลูกเมื่อโหลดแม่ เพียงแค่ทำให้ lazy = false และ hibernate จะโหลดลูกเมื่อมีการโหลดพาเรนต์จากฐานข้อมูล Exampleslazy = true (ค่าเริ่มต้น) แอดเดรสลูกของคลาสผู้ใช้สามารถทำให้ขี้เกียจหากไม่จำเป็นต้องใช้บ่อย
Lazy loading เป็นรูปแบบการออกแบบที่ใช้กันทั่วไปในการเขียนโปรแกรมคอมพิวเตอร์เพื่อเลื่อนการเริ่มต้นของวัตถุจนกระทั่งถึงจุดที่ต้องการ มันสามารถช่วยเพิ่มประสิทธิภาพในการทำงานของโปรแกรมหากใช้อย่างเหมาะสมและเหมาะสม
วิกิพีเดีย
ลิงค์ของLazy Loadingจาก hibernate.org
มันก็หมายถึงการโหลดข้อมูลที่คุณต้องการในปัจจุบันแทนที่จะโหลดทั้งกลุ่มในคราวเดียวซึ่งคุณจะไม่ใช้ตอนนี้ ทำให้ความเร็วในการโหลดแอปพลิเคชันเร็วกว่าปกติ
Hiberante รองรับคุณสมบัติของการเริ่มต้นขี้เกียจสำหรับเอนทิตีและคอลเลกชัน เอ็นจินไฮเบอร์เนตโหลดเฉพาะวัตถุเหล่านั้นที่เรากำลังสอบถามไม่ได้รับสิทธิ์หรือคอลเลกชันอื่น ๆ
สันหลังยาว = "false" โดยค่าเริ่มต้นการโหลดเริ่มต้นพูดถึงสำหรับเด็กเพียงคนเดียวคือกรณี lazy.in ของจริงที่เป็นผู้ปกครองกำลังโหลดไม่สนับสนุนเด็ก
การตั้งค่า Lazy ตัดสินใจว่าจะโหลดวัตถุลูกในขณะที่โหลดวัตถุหลักหรือไม่คุณต้องทำการตั้งค่าไฟล์การทำแผนที่จำศีลตามลำดับของคลาสผู้ปกครอง Lazy = true (หมายถึงไม่โหลดเด็ก) โดยค่าเริ่มต้นการโหลดวัตถุวัตถุลูกนั้นเป็นจริง .
น่าแปลกที่ไม่มีคำตอบพูดคุยเกี่ยวกับวิธีที่จะประสบความสำเร็จโดยจำศีลหลังหน้าจอ
การโหลดแบบ Lazyเป็นรูปแบบการออกแบบที่ใช้อย่างมีประสิทธิภาพในโหมดไฮเบอร์เนตด้วยเหตุผลด้านประสิทธิภาพซึ่งเกี่ยวข้องกับเทคนิคต่อไปนี้
1. การวัดรหัสไบต์ :
ปรับปรุงนิยามคลาสพื้นฐานด้วยhooks hibernate เพื่อสกัดกั้นการเรียกทั้งหมดไปยังวัตถุเอนทิตีนั้น
ทำได้ทั้งในเวลารวบรวมหรือเรียกใช้เวลา [โหลด]
1.1 เวลารวบรวม
โพสต์การดำเนินการรวบรวมเวลา
ส่วนใหญ่เป็นปลั๊กอิน maven / ant
1.2 เวลาทำงาน
วัตถุเอนทิตีที่ส่งกลับไฮเบอร์เนตเป็นพร็อกซีของประเภทจริง
ดูเพิ่มเติม: Javassist แนวคิดหลักและที่ใช้งานจริงคืออะไร?