2.1 ตัวเลือกการดึงข้อมูล

นักพัฒนาของ Hibernate ทราบเกี่ยวกับปัญหาในการโหลดเอนทิตีย่อยมาเป็นเวลานาน สิ่งแรกที่พวกเขาทำคือเพิ่ม พารามิเตอร์ การดึงข้อมูลพิเศษให้กับคำอธิบายประกอบ@OneToMany,@ManyToMany

พารามิเตอร์นี้สามารถรับได้สองค่า:

  • กระตือรือร้น
  • ขี้เกียจ

ตัวอย่าง:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")

หากพารามิเตอร์การดึงข้อมูลเท่ากับ EAGERเมื่อโหลดเอนทิตีหลัก เอนทิตีย่อยทั้งหมดจะถูกโหลดด้วย นอกจากนี้ Hibernate จะพยายามทำในแบบสอบถาม SQL เดียว สร้างแบบสอบถามที่แข็งแรงและดึงข้อมูลทั้งหมดในคราวเดียว

หากพารามิเตอร์การดึงข้อมูลใช้ค่า LAZYเมื่อเอนทิตีหลักถูกโหลด เอนทิตีย่อยจะไม่ถูกโหลด จะมีการสร้างวัตถุพร็อกซีแทน

ด้วยความช่วยเหลือของวัตถุพร็อกซีนี้ ไฮเบอร์เนตจะติดตามการเข้าถึงเอนทิตีย่อยนี้และโหลดลงในหน่วยความจำในครั้งแรกที่มีการเข้าถึง

หากเราจำสถานการณ์ของเราด้วยความคิดเห็น:


@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;
 
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   @JoinColumn(name = "user_id")
   public List<Comment> comments;
}

จากนั้นคุณมี "ทางเลือกที่เก๋ไก๋":

ถ้าfetch = FetchType.EAGERHibernate จะโหลดความคิดเห็นทั้งหมดในบรรทัดที่ 1 ของโค้ด:

User user = session.get(User.class, 1);		//load all comments here
List<Comment> comments = user.getComments();

ถ้าfetch = FetchType.LAZYHibernate จะโหลดความคิดเห็นทั้งหมดในโค้ดบรรทัดที่ 2:

User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here

อย่างที่คุณเดาได้ คุณไม่มีทางเลือกเมื่อมันไม่โหลดความคิดเห็นทั้งหมด :)

2.2 ค่าเริ่มต้น

หากคุณไม่ระบุตัวเลือกการดึงข้อมูลสำหรับ@ManyToคำอธิบายประกอบ ... จากนั้น Hibernate จะใช้ค่าเริ่มต้น

ซึ่งจะแตกต่างกันเล็กน้อยสำหรับคำอธิบายประกอบประเภทต่างๆ สำหรับคำอธิบายประกอบ@OneToOneและ@ManyToOneกระตือรือร้น สำหรับคำอธิบายประกอบ@OneToManyและ@ManyToManyขี้เกียจ ง่ายต่อการจดจำ - หากเราอ้างถึงวัตถุชิ้นเดียว วัตถุนั้นจะถูกโหลดอย่างสมบูรณ์ หากเราอ้างถึงคอลเลกชั่น มันจะถูกโหลดในครั้งแรกที่มีการเข้าถึง

2.3 คำอธิบายประกอบ @LazyCollection

ดังที่คุณได้เห็นแล้ว พารามิเตอร์การดึงข้อมูลไม่ได้ช่วยอะไรมากนักเมื่อทำงานกับคอลเลกชัน ผู้สร้าง Hibernate พยายามแก้ไขปัญหานี้โดยเพิ่มคำอธิบายประกอบ@LazyCollectionพิเศษ โดยปกติจะเขียนดังนี้:

@LazyCollection(LazyCollectionOption.TRUE)

คุณต้องระบุเมื่อแมปฟิลด์คอลเลกชัน:


@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;
 
   @OneToMany(cascade = CascadeType.ALL)
   @LazyCollection(LazyCollectionOption.TRUE)
   public List<Comment> comments;
}

คำอธิบายประกอบนี้มีพารามิเตอร์ค่าที่สามารถรับหนึ่งในสามค่า:

  • ตัวเลือก LazyCollection จริง
  • ตัวเลือก LazyCollection เท็จ
  • ตัวเลือก LazyCollection พิเศษ

สองตัวเลือกแรกคล้ายกับตัวเลือกการดึงข้อมูลมาก

หากตั้งค่าพารามิเตอร์เป็นLazyCollectionOption.TRUEหมายความว่าค่าของฟิลด์ความคิดเห็นจะไม่ถูกโหลดจากฐานข้อมูลเมื่อโหลดออบเจกต์ผู้ใช้หลัก อ็อบเจกต์ประเภท Comment จะถูกโหลดในครั้งแรกที่มีการเข้าถึงฟิลด์ความคิดเห็น ในความเป็นจริงนี้เทียบเท่ากับพารามิเตอร์FetchType.LAZY

หากตั้งค่าพารามิเตอร์เป็นLazyCollectionOption.FALSEหมายความว่าค่าของฟิลด์ความคิดเห็นจะถูกโหลดจากฐานข้อมูลในเวลาที่โหลดวัตถุผู้ใช้หลัก อ็อบเจกต์ประเภท Comment จะถูกโหลดในครั้งแรกที่มีการเข้าถึงฟิลด์ความคิดเห็น ในความเป็นจริงนี้เทียบเท่ากับFetchType.EAGER.