2.1 tùy chọn tìm nạp
Các nhà phát triển Hibernate đã biết về vấn đề tải các thực thể con từ lâu. Vì vậy, điều đầu tiên họ làm là thêm một tham số tìm nạp đặc biệt vào các chú thích @OneToMany
, @ManyToMany
.
Tham số này có thể nhận hai giá trị:
- HÁO HỨC
- LƯỜI
Ví dụ:
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
Nếu tham số tìm nạp bằng EAGER thì khi thực thể mẹ được tải, tất cả các thực thể con của nó cũng sẽ được tải. Ngoài ra, Hibernate sẽ cố gắng thực hiện điều đó trong một truy vấn SQL, tạo ra một truy vấn lớn và tìm nạp tất cả dữ liệu cùng một lúc.
Nếu tham số tìm nạp nhận giá trị LAZY thì khi thực thể mẹ được tải, thực thể con sẽ không được tải. Thay vào đó, một đối tượng proxy sẽ được tạo.
Với sự trợ giúp của đối tượng proxy này, Hibernate sẽ theo dõi quyền truy cập vào thực thể con này và tải nó vào bộ nhớ trong lần truy cập đầu tiên.
Nếu chúng tôi nhớ lại tình huống của mình với các nhận xét:
@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;
}
Sau đó, bạn có một "sự lựa chọn sang trọng":
Nếu fetch = FetchType.EAGER
, thì Hibernate sẽ tải tất cả các nhận xét trên dòng mã đầu tiên:
User user = session.get(User.class, 1); //load all comments here
List<Comment> comments = user.getComments();
Nếu fetch = FetchType.LAZY
, thì Hibernate sẽ tải tất cả các nhận xét trên dòng mã thứ 2:
User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here
Như bạn có thể đoán, bạn không có tùy chọn nào khi nó không tải tất cả các bình luận :)
2.2 Giá trị mặc định
Nếu bạn không chỉ định tùy chọn tìm nạp cho @ManyTo
chú thích ... thì Hibernate sẽ sử dụng các giá trị mặc định.
Chúng hơi khác nhau đối với các loại chú thích khác nhau. Đối với các chú thích @OneToOne
và @ManyToOne
HÃY THAM GIA, đối với các chú thích @OneToMany
và @ManyToMany
LƯỜI. Thật dễ nhớ - nếu chúng ta đề cập đến một đối tượng, thì nó sẽ được tải hoàn toàn. Nếu chúng ta đề cập đến một bộ sưu tập, thì nó sẽ được tải vào lần đầu tiên được truy cập.
2.3 Chú thích @LazyCollection
Như bạn đã thấy, tham số tìm nạp không giúp ích nhiều khi làm việc với các tập hợp. Những người tạo ra Hibernate đã cố gắng khắc phục điều này bằng cách thêm một chú thích đặc biệt @LazyCollection
. Nó thường được viết như thế này:
@LazyCollection(LazyCollectionOption.TRUE)
Bạn cần chỉ định nó khi ánh xạ các trường bộ sưu tập:
@Entity
@Table(name="user")
class User {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.TRUE)
public List<Comment> comments;
}
Chú thích này có một tham số giá trị có thể nhận một trong ba giá trị:
- LazyCollectionOption. ĐÚNG VẬY
- LazyCollectionOption. SAI
- LazyCollectionOption. THÊM
Hai tùy chọn đầu tiên rất giống với tùy chọn tìm nạp.
Nếu tham số được đặt thành LazyCollectionOption.TRUE
, điều đó có nghĩa là các giá trị của trường nhận xét sẽ không được tải từ cơ sở dữ liệu khi đối tượng Người dùng mẹ được tải. Các đối tượng của loại Nhận xét sẽ được tải vào lần đầu tiên trường nhận xét được truy cập. Trên thực tế, điều này tương đương với tham sốFetchType.LAZY
Nếu tham số được đặt thành LazyCollectionOption.FALSE
, điều đó có nghĩa là các giá trị của trường nhận xét sẽ được tải từ cơ sở dữ liệu tại thời điểm tải đối tượng Người dùng chính. Các đối tượng của loại Nhận xét sẽ được tải vào lần đầu tiên trường nhận xét được truy cập. Trên thực tế, điều này tương đương với FetchType.EAGER
.