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 @ManyTochú 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@ManyToOneHÃY THAM GIA, đối với các chú thích @OneToMany@ManyToManyLƯỜ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.