Háo hức / lười biếng tải trong chế độ ngủ đông

Độ bền hàng đầu

Tôi vừa công bố khóa học Learn Spring mới , tập trung vào các nguyên tắc cơ bản của Spring 5 và Spring Boot 2:

>> KIỂM TRA KHÓA HỌC

1. Giới thiệu

Khi làm việc với ORM, tìm nạp / tải dữ liệu có thể được phân thành hai loại: háo hức và lười biếng.

Trong bài viết nhanh này, chúng tôi sẽ chỉ ra những điểm khác biệt và chỉ ra những điểm khác biệt có thể được sử dụng trong Hibernate.

2. Sự phụ thuộc của Maven

Để sử dụng Hibernate, trước tiên hãy xác định phụ thuộc chính trong pom.xml của chúng tôi :

 org.hibernate hibernate-core 5.2.2.Final 

Bạn có thể tìm thấy phiên bản mới nhất của Hibernate tại đây.

3. Háo hức và lười biếng tải

Điều đầu tiên mà chúng ta nên thảo luận ở đây là tải chậm và tải háo hức là gì:

  • Eager Loading là một mẫu thiết kế trong đó việc khởi tạo dữ liệu diễn ra ngay tại chỗ
  • Lazy Loading là một mẫu thiết kế được sử dụng để trì hoãn việc khởi tạo một đối tượng miễn là nó có thể

Hãy xem điều này thực sự hoạt động như thế nào với một số ví dụ:

Các UserLazy lớp :

@Entity @Table(name = "USER") public class UserLazy implements Serializable { @Id @GeneratedValue @Column(name = "USER_ID") private Long userId; @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") private Set orderDetail = new HashSet(); // standard setters and getters // also override equals and hashcode }

Lớp OrderDetail :

@Entity @Table (name = "USER_ORDER") public class OrderDetail implements Serializable { @Id @GeneratedValue @Column(name="ORDER_ID") private Long orderId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="USER_ID") private UserLazy user; // standard setters and getters // also override equals and hashcode }

Một người dùng có thể có nhiều OrderDetails . Trong chiến lược tải háo hức, nếu chúng tôi tải dữ liệu Người dùng , dữ liệu đó cũng sẽ tải tất cả các đơn hàng liên quan đến nó và sẽ lưu trữ trong bộ nhớ .

Tuy nhiên, khi kích hoạt tính năng tải chậm , nếu chúng tôi kéo một UserLazy lên , dữ liệu OrderDetail sẽ không được khởi tạo và tải vào bộ nhớ cho đến khi một lệnh gọi rõ ràng được thực hiện đến nó.

Trong phần tiếp theo, chúng ta sẽ xem ví dụ trên được triển khai như thế nào trong Hibernate.

4. Đang tải cấu hình

Trong phần này, chúng ta sẽ xem xét cách chúng ta có thể định cấu hình các chiến lược tìm nạp trong Hibernate. Chúng tôi sẽ sử dụng lại các ví dụ từ phần trước.

Có thể chỉ cần bật Lazy Loading bằng cách sử dụng tham số chú thích sau:

fetch = FetchType.LAZY

Để sử dụng Eager Fetching, thông số sau được sử dụng:

fetch = FetchType.EAGER

Để thiết lập Háo hức tải, chúng tôi đã sử dụng UserLazy lớp đôi 's gọi UserEager .

Trong phần tiếp theo, chúng ta sẽ xem xét sự khác biệt giữa hai kiểu tìm nạp.

5. Sự khác biệt

Như chúng tôi đã đề cập, sự khác biệt chính giữa hai kiểu tìm nạp là thời điểm khi dữ liệu được tải vào bộ nhớ.

Hãy xem ví dụ này:

List users = sessionLazy.createQuery("From UserLazy").list(); UserLazy userLazyLoaded = users.get(3); return (userLazyLoaded.getOrderDetail());

Với phương pháp khởi tạo lười biếng, orderDetailSet sẽ chỉ được khởi tạo khi nó được gọi một cách rõ ràng bằng cách sử dụng getter hoặc một số phương thức khác như trong ví dụ trên:

UserLazy userLazyLoaded = users.get(3);

Nhưng với cách tiếp cận háo hức trong UserEager, nó sẽ được khởi tạo ngay lập tức trong dòng đầu tiên của ví dụ trên:

List user = sessionEager.createQuery("From UserEager").list();

Đối với tải chậm, một đối tượng proxy được sử dụng và một truy vấn SQL riêng biệt được kích hoạt để tải orderDetailSet .

Ý tưởng vô hiệu hóa proxy hoặc tải chậm được coi là một phương pháp không tốt trong Hibernate. Nó có thể dẫn đến nhiều dữ liệu được tìm nạp từ cơ sở dữ liệu và được lưu trữ trong bộ nhớ, bất kể nhu cầu của nó là gì.

Phương pháp sau có thể được sử dụng để kiểm tra chức năng trên:

Hibernate.isInitialized(orderDetailSet);

Bây giờ, điều quan trọng là phải xem xét các truy vấn được tạo trong cả hai trường hợp:

true

Cài đặt trên trong fetching.hbm.xml hiển thị các truy vấn SQL được tạo. Nếu bạn nhìn vào đầu ra bảng điều khiển thì bạn sẽ có thể thấy các truy vấn đã tạo.

Đối với Lazy Tải truy vấn được tạo để tải dữ liệu Người dùng :

select user0_.USER_ID as USER_ID1_0_, ... from USER user0_

Tuy nhiên, trong quá trình tải háo hức, chúng tôi đã thấy một tham gia được thực hiện với USER_ORDER:

select orderdetai0_.USER_ID as USER_ID4_0_0_, orderdetai0_.ORDER_ID as ORDER_ID1_1_0_, orderdetai0_ ... from USER_ORDER orderdetai0_ where orderdetai0_.USER_ID=?

Truy vấn trên được tạo cho tất cả Người dùng , dẫn đến việc sử dụng nhiều bộ nhớ hơn so với cách tiếp cận khác.

6. Ưu điểm và nhược điểm

6.1. Đang tải chậm

Ưu điểm:

  • Thời gian tải ban đầu nhỏ hơn nhiều so với cách tiếp cận khác
  • Tiêu thụ bộ nhớ ít hơn so với cách tiếp cận khác

Disadvantages:

  • Delayed initialization might impact performance during unwanted moments
  • In some cases you need to handle lazily-initialized objects with a special care or you might end up with an exception

6.2. Eager Loading:

Advantages:

  • No delayed initialization related performance impacts

Disadvantages:

  • Long initial loading time
  • Loading too much unnecessary data might impact performance

7. Lazy Loading in Hibernate

Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation of classes.

Hibernate intercepts calls to an entity by substituting it with a proxy derived from an entity’s class. In our example, when a requested information is missing, it will be loaded from a database before control is ceded to the User class implementation.

Cũng cần lưu ý rằng khi liên kết được biểu diễn dưới dạng một lớp tập hợp (trong các ví dụ trên, nó được biểu diễn dưới dạng Set orderDetailSet ), thì một trình bao bọc được tạo và thay thế cho một tập hợp ban đầu.

Để biết thêm về mẫu thiết kế proxy bạn có thể tham khảo tại đây.

8. Kết luận

Trong bài viết này, chúng tôi đã đưa ra các ví dụ về hai kiểu tìm nạp chính được sử dụng trong Hibernate.

Đối với trình độ chuyên môn nâng cao, bạn có thể xem trên trang web chính thức của Hibernate. Để lấy mã được thảo luận trong bài viết này, vui lòng xem qua kho này.

Độ bền đáy

Tôi vừa công bố khóa học Learn Spring mới , tập trung vào các nguyên tắc cơ bản của Spring 5 và Spring Boot 2:

>> KIỂM TRA KHÓA HỌC