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.EAGER
Hibernate จะโหลดความคิดเห็นทั้งหมดในบรรทัดที่ 1 ของโค้ด:
User user = session.get(User.class, 1); //load all comments here
List<Comment> comments = user.getComments();
ถ้าfetch = FetchType.LAZY
Hibernate จะโหลดความคิดเห็นทั้งหมดในโค้ดบรรทัดที่ 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
.
GO TO FULL VERSION