Tải lười biếng trong Hibernate là gì?


178

Tải lười biếng trong Java là gì? Tôi không hiểu quy trình. Ai có thể giúp tôi hiểu quá trình tải lười biếng?

Câu trả lời:


268

Giả sử bạn có cha mẹ và cha mẹ đó có một bộ sưu tập con cái. Giờ ngủ đông có thể "lười tải" trẻ em, điều đó có nghĩa là nó không thực sự tải tất cả trẻ em khi tải cha mẹ. Thay vào đó, nó tải chúng khi được yêu cầu làm như vậy. Bạn có thể yêu cầu điều này một cách rõ ràng hoặc, và điều này phổ biến hơn nhiều, ngủ đông sẽ tự động tải chúng khi bạn cố gắng truy cập một đứa trẻ.

Tải nhanh có thể giúp cải thiện hiệu suất đáng kể vì thường bạn sẽ không cần trẻ em và vì vậy chúng sẽ không được tải.

Cũng hãy cẩn thận với vấn đề n + 1. Hibernate sẽ không thực sự tải tất cả trẻ em khi bạn truy cập vào bộ sưu tập. Thay vào đó, nó sẽ tải từng đứa trẻ. Khi lặp qua bộ sưu tập, điều này gây ra một truy vấn cho mọi đứa trẻ. Để tránh điều này, bạn có thể lừa ngủ đông đồng thời tải tất cả trẻ em, ví dụ: bằng cách gọi Parent.getChildren (). Size ().


5
Ngoài ra, nên sử dụng Hibernate.initialize (Parent.getChildren ())
HakunaMatata

18
Câu lệnh "khi bạn truy cập vào bộ sưu tập ... nó sẽ tải từng đứa trẻ" thực sự không chính xác. Nó thực sự hoàn toàn ngược lại. Bất kỳ sự quy định nào của Parent.getChildren () sẽ khiến Hibernate tải tất cả các phần tử con trong bộ sưu tập trong một truy vấn db. Trừ khi bạn sử dụng gợi ý tải "lười biếng" rất đặc biệt. Hoặc trừ khi bạn lưu trữ bộ sưu tập trong bộ đệm cấp hai và những đứa trẻ liên quan cũng không được lưu vào bộ đệm.
Steve Ebersole

Ồ, Stack Overflow - câu trả lời hay nhất được tìm thấy ở cuối trang ;-)
Piotrek Hryciuk

76

"Lazy tải" có nghĩa rằng một thực thể sẽ được nạp chỉ khi bạn thực sự truy cập các thực thể cho đầu tiên thời gian.

Các mô hình là như thế này:

public Entity getEntity() {
    if (entity == null) {
        entity = loadEntity();
    }
    return entity;
}

Điều này giúp tiết kiệm chi phí tải trước / nạp trước tất cả các thực thể trong một tập dữ liệu lớn trước khi bạn thực sự không cần tất cả chúng.

Trong Hibernate, bạn có thể định cấu hình để tải một cách nhanh chóng một bộ sưu tập các thực thể con. Các thực tế sau đó lười tải được thực hiện bên trong các phương pháp của PersistentSetmà Hibernate sử dụng "dưới mũ trùm" chuyển nhượng bộ sưu tập của các đối tượng như Set.

Ví dụ

public class Parent {
    private Set<Child> children;

    public Set<Child> getChildren() {
        return children;
    }
}

.

public void doSomething() {
    Set<Child> children = parent.getChildren(); // Still contains nothing.

    // Whenever you call one of the following (indirectly), 
    // Hibernate will start to actually load and fill the set.
    children.size();
    children.iterator();
}

25

Martin Fowler định nghĩa mẫu Lazy Load trong Các mẫu của Kiến trúc ứng dụng doanh nghiệp như sau:

Một đối tượng không chứa tất cả dữ liệu bạn cần nhưng biết cách lấy nó.

Vì vậy, khi tải một đối tượng nhất định, ý tưởng là không háo hức tải (các) đối tượng liên quan mà bạn không thể sử dụng ngay lập tức để tiết kiệm chi phí hiệu suất liên quan. Thay vào đó, (các) đối tượng liên quan sẽ chỉ được tải khi được sử dụng.

Đây không phải là mẫu dành riêng cho truy cập dữ liệu và Hibernate nhưng nó đặc biệt hữu ích trong các lĩnh vực như vậy và Hibernate hỗ trợ lười biếng tải các liên kết một-nhiều và liên kết một điểm (một-một và nhiều-một) dưới một số điều kiện nhất định. Tương tác lười biếng được thảo luận chi tiết hơn trong Chương 19 của Tài liệu tham khảo Hibernate 3.0.


15

Bydefault tải chậm là đúng. Tải có nghĩa là khi truy vấn chọn được thực thi, nó sẽ không truy cập cơ sở dữ liệu. Nó sẽ đợi hàm getter tức là khi chúng ta yêu cầu, nó sẽ tìm nạp từ cơ sở dữ liệu. ví dụ: Bạn là cha mẹ có một đứa trẻ với rất nhiều đồ chơi. Nhưng vấn đề hiện tại là bất cứ khi nào bạn gọi anh ấy (chúng tôi cho rằng bạn có con trai), anh ấy cũng đến với bạn bằng tất cả đồ chơi của anh ấy. Bây giờ đây là một vấn đề vì bạn không muốn anh ấy mang theo đồ chơi mọi lúc. Vì vậy, là cha mẹ hợp lý, bạn đi thẳng và xác định đồ chơi của trẻ là LAZY. Bây giờ bất cứ khi nào bạn gọi anh ta, anh ta chỉ đến với bạn mà không có đồ chơi của anh ta.


11

Tìm nạp lười biếng quyết định có tải các đối tượng con trong khi tải Đối tượng gốc hay không. Bạn cần thực hiện cài đặt này tệp ánh xạ ngủ đông tương ứng của lớp cha. Lazy = true(có nghĩa là không tải con) Theo mặc định, tải lười biếng của các đối tượng con là đúng.

Điều này đảm bảo rằng các đối tượng con không được tải trừ khi chúng được gọi một cách rõ ràng trong ứng dụng bằng cách gọi getChild()phương thức trên cha. Trong trường hợp này, chế độ ngủ đông phát ra một lệnh gọi cơ sở dữ liệu mới để tải con khi getChild()được gọi một cách chính xác trên đối tượng Parent.

Nhưng trong một số trường hợp, bạn cần phải tải các đối tượng con khi cha mẹ được tải. Chỉ cần làm cho lazy = false và ngủ đông sẽ tải con khi cha mẹ được tải từ cơ sở dữ liệu.

Ví dụ: Nếu bạn có BẢNG? NHÂN VIÊN ánh xạ tới đối tượng Nhân viên và chứa tập hợp các đối tượng Địa chỉ. Lớp phụ huynh: Lớp nhân viên, Lớp con: Lớp địa chỉ

public class Employee { 
private Set address = new HashSet(); // contains set of child Address objects 
public Set getAddress () { 
return address; 
} 
public void setAddresss(Set address) { 
this. address = address; 
} 
} 

Trong tệp Employee.hbm.xml

<set name="address" inverse="true" cascade="delete" lazy="false"> 
<key column="a_id" /> 
<one-to-many class="beans Address"/> 
</set> 

Trong cấu hình trên. Nếu lazy="false": - khi bạn tải đối tượng Nhân viên, thời gian đó đối tượng con Địa chỉ cũng được tải và được đặt thành phương thức setAddresss (). Nếu bạn gọi worker.getAdress () thì dữ liệu được tải trở lại. Không có cuộc gọi cơ sở dữ liệu mới.

Nếu lazy="true": - Đây là cấu hình mặc định. Nếu bạn không đề cập thì ngủ đông hãy xem xét lười biếng = đúng. khi bạn tải đối tượng Nhân viên thời gian đó đối tượng con Địa chỉ không được tải. Bạn cần thêm cuộc gọi đến cơ sở dữ liệu để có được các đối tượng địa chỉ. Nếu bạn gọi employee.getAdress()thì truy vấn cơ sở dữ liệu thời gian đó kích hoạt và trả về kết quả. Cuộc gọi cơ sở dữ liệu mới.


Nhân viên và Địa chỉ không có mối quan hệ Cha-Con trong kịch bản này. Đó là mối quan hệ 'có-một' !
Ram

Đây là tổng hợp không kế thừa.
Rishi

11

Trong ngôn ngữ của giáo dân, giống như bạn đang làm bánh và bạn sẽ cần 5-10 nguyên liệu từ tủ lạnh. Bạn có hai lựa chọn, lấy tất cả các thành phần từ tủ lạnh và đặt nó trên nền tảng nhà bếp của bạn, hoặc mang theo món đồ bạn muốn khi bạn cần.

Tương tự, trong quá trình tải háo hức, bạn lấy tất cả thông tin về đậu và các lớp liên quan của nó (không phải là quan hệ trẻ em hay quan hệ nhưng có mối quan hệ, ví dụ như bánh có bột, có sữa, có kem, v.v.) và trong trường hợp lười tải, trước tiên bạn chỉ mang theo mã định danh và các giá trị đến từ cùng một bảng (các thành phần cần thiết mà trước tiên bạn sẽ cần trong bát của mình trong trường hợp bánh). Tất cả thông tin đến từ các bảng khác sẽ được tìm nạp và khi được yêu cầu / sử dụng.


8

Lười tải? Chà, điều đó đơn giản có nghĩa là hồ sơ con không được tìm nạp ngay lập tức mà tự động ngay khi bạn cố gắng truy cập chúng.


3

Cài đặt lười biếng quyết định có tải các đối tượng con trong khi tải Đối tượng cha hay không. Bạn cần thực hiện cài đặt này đối với tệp ánh xạ ngủ đông tương ứng của lớp cha.Lazy = true (có nghĩa là không tải con) Theo mặc định, tải lười biếng của các đối tượng con là đúng . Điều này đảm bảo rằng các đối tượng con không được tải trừ khi chúng được gọi một cách rõ ràng trong ứng dụng bằng cách gọi phương thức getChild () trên cha. object.Nhưng trong một số trường hợp bạn cần tải các đối tượng con khi tải cha. Chỉ cần làm cho lazy = false và hibernate sẽ tải con khi cha mẹ được tải từ cơ sở dữ liệu.Exampleslazy = true (mặc định) Địa chỉ con của lớp Người dùng có thể bị lười biếng nếu không được yêu cầu thường xuyên.


3

Tải nhanh cho phép bạn trì hoãn việc truy xuất liên kết hoặc để kiểm soát tốt hơn đối với chiến lược tìm nạp.

Khi bạn sử dụng tải EAGER, bạn xác định gói tìm nạp toàn cầu không thể ghi đè tại thời điểm truy vấn, nghĩa là bạn bị giới hạn trong quyết định bạn đã đưa ra trong khi thiết kế mô hình thực thể của mình. Tìm nạp EAGER là một mùi mã , bởi vì chiến lược tìm nạp là một chính sách thời gian truy vấn và nó có thể khác với trường hợp sử dụng kinh doanh khác.

Các chiến lược quyến rũ là một khía cạnh rất quan trọng, vì quá nhiều quyến rũ háo hức có thể gây ra vấn đề hiệu suất liên quan nghiêm trọng.


2

Tải lười biếng là một mẫu thiết kế thường được sử dụng trong lập trình máy tính để trì hoãn việc khởi tạo một đối tượng cho đến thời điểm cần thiết. Nó có thể đóng góp vào hiệu quả trong hoạt động của chương trình nếu được sử dụng đúng cách và phù hợp

Wikipedia

Liên kết của Lazy Loading từ hibernate.org


1

Vâng, nó đơn giản có nghĩa là tải dữ liệu bạn cần hiện tại thay vì tải toàn bộ dữ liệu cùng một lúc mà bạn sẽ không sử dụng ngay bây giờ. Qua đó làm cho thời gian tải ứng dụng nhanh hơn bình thường.


0

Hiberante hỗ trợ tính năng khởi tạo lười biếng cho cả thực thể và bộ sưu tập. Công cụ ngủ đông chỉ tải những đối tượng mà chúng tôi đang truy vấn không có các quyền hoặc bộ sưu tập khác.

lazy = "false" theo mặc định tải khởi tạo đề cập cho đứa trẻ duy nhất là lazy. Trong trường hợp đúng là cha mẹ đang tải không hỗ trợ con


0

Cài đặt lười biếng quyết định có tải các đối tượng con trong khi tải Đối tượng cha hay không. Bạn cần thực hiện cài đặt này tệp ánh xạ ngủ đông tương ứng của lớp cha.Lazy = true (có nghĩa là không tải con) Theo mặc định, tải lười biếng của các đối tượng con là đúng .


0

Đáng ngạc nhiên, không có câu trả lời nào nói về cách đạt được bằng cách ngủ đông đằng sau màn hình.

Lazy load là một mẫu thiết kế được sử dụng hiệu quả trong chế độ ngủ đông vì lý do hiệu suất bao gồm các kỹ thuật sau.


1. Thiết bị mã byte :

Tăng cường định nghĩa lớp cơ sở với các móc ngủ đông để chặn tất cả các cuộc gọi đến đối tượng thực thể đó.

Thực hiện vào thời gian biên dịch hoặc chạy thời gian [tải]

1.1 Biên dịch thời gian

  • Hoạt động thời gian biên dịch bài

  • Chủ yếu là bởi các plugin maven / ant

1.2 Thời gian chạy

  • Nếu không có công cụ thời gian biên dịch nào được thực hiện, thì công cụ này được tạo vào thời gian chạy Sử dụng các thư viện như javassist

2. Proxy

Đối tượng thực thể mà Hibernate trả về là proxy của loại thực.

Xem thêm: Javassist. Ý tưởng chính và sử dụng thực sự ở đâu?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.