Что такое ленивая загрузка в Hibernate? - PullRequest
164 голосов
/ 03 февраля 2010

Что такое ленивая загрузка в Java? Я не понимаю процесс. Кто-нибудь может помочь мне понять процесс отложенной загрузки?

Ответы [ 14 ]

257 голосов
/ 03 февраля 2010

Скажем, у вас есть родитель, и у этого родителя есть коллекция детей. Hibernate теперь может «лениво загружать» дочерние элементы, что означает, что он фактически не загружает все дочерние элементы при загрузке родительского элемента. Вместо этого он загружает их по запросу. Вы можете запросить это явно или, что гораздо чаще, hibernate будет загружать их автоматически при попытке доступа к дочернему элементу.

Lazy-loading может помочь значительно улучшить производительность, так как часто вам не нужны дети, и поэтому они не будут загружаться.

Также остерегайтесь проблемы n + 1. Hibernate не будет загружать все дочерние элементы при доступе к коллекции. Вместо этого он будет загружать каждого ребенка в отдельности. При переборе по коллекции это вызывает запрос для каждого дочернего элемента. Чтобы избежать этого, вы можете обмануть спящий режим, загружая всех детей одновременно, например, вызывая parent.getChildren (). size ().

71 голосов
/ 03 февраля 2010

«Ленивая загрузка» означает, что объект будет загружен только , когда вы на самом деле получите доступ к объекту в течение первого времени.

Шаблон выглядит следующим образом:

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

Это экономит затраты на предварительную загрузку / предварительное заполнение всех объектов в большом наборе данных заранее, в то время как вам на самом деле не нужны все из них.

В Hibernate вы можете настроить ленивую загрузку коллекции дочерних объектов. Затем фактическая ленивая загрузка выполняется внутри методов PersistentSet, которые Hibernate использует "под капотами", чтобы назначить коллекцию сущностей как Set.

1028 * Е.Г. *

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();
}
24 голосов
/ 04 февраля 2010

Мартин Фаулер определяет шаблон Lazy Load в Шаблоны архитектуры корпоративных приложений следующим образом:

Объект, который не содержит всех необходимых вам данных, но знает, как их получить.

Таким образом, идея при загрузке данного объекта заключается в том, чтобы не стремиться загрузить связанный объект (ы), который вы не можете использовать немедленно, чтобы сэкономить связанные затраты производительности. Вместо этого связанный объект (ы) будет загружен только при использовании.

Это не шаблон, специфичный для доступа к данным и Hibernate, но он особенно полезен в таких областях, и Hibernate поддерживает ленивую загрузку ассоциаций «один ко многим» и ассоциаций «один к одному» и «многие к один) также при определенных условиях. Ленивое взаимодействие обсуждается более подробно в Глава 19 Справочной документации по Hibernate 3.0.

15 голосов
/ 31 января 2013

По умолчанию отложенная загрузка имеет значение true. Ленивая загрузка означает, что при выполнении запроса select он не попадет в базу данных. Он будет ожидать функцию получения, то есть когда нам потребуется, он будет извлекаться из базы данных. например: Вы родитель, у которого есть ребенок с большим количеством игрушек. Но текущая проблема в том, что когда бы ты ни позвонил ему (мы предполагаем, что у тебя есть мальчик), он приходит к тебе со всеми своими игрушками. Теперь это проблема, так как вы не хотите, чтобы он все время носил свои игрушки. Таким образом, будучи обоснованным родителем, вы идете вперед и определяете игрушки ребенка как ленивые. Теперь, когда бы ты ни позвонил ему, он просто приходит к тебе без игрушек.

11 голосов
/ 31 мая 2013

Ленивая выборка решает, загружать ли дочерние объекты при загрузке родительского объекта. Вы должны сделать эту настройку соответствующим файлом отображения гибернации родительского класса. Lazy = true (означает не загружать ребенка) По умолчанию отложенная загрузка дочерних объектов имеет значение true.

Это гарантирует, что дочерние объекты не загружаются, если они не были явно вызваны в приложении путем вызова метода getChild() для parent. В этом случае hibernate выдает новый вызов базы данных для загрузки дочернего объекта, когда getChild() вызывается фактически на родительском объекте.

Но в некоторых случаях вам нужно загружать дочерние объекты при загрузке родительского объекта. Просто сделайте lazy = false, и hibernate загрузит дочерний элемент при загрузке parent из базы данных.

Пример: Если у вас есть СТОЛ? EMPLOYEE отображается на объект Employee и содержит набор объектов Address. Родительский класс: класс сотрудника, Дочерний класс: Адрес класса

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; 
} 
} 

В файле Employee.hbm.xml

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

В вышеуказанной конфигурации. Если lazy="false": - при загрузке объекта Employee в это время также загружается дочерний объект Address и устанавливается метод setAddresss (). Если вы вызываете employee.getAdress (), то загруженные данные возвращаются. Нет нового вызова базы данных.

Если lazy="true": - это конфигурация по умолчанию. Если вы не упомянули, то в спящем режиме считайте lazy = true. при загрузке объекта Employee дочерний объект Adress того времени не загружается. Вам нужен дополнительный вызов в базу данных, чтобы получить адресные объекты. Если вы наберете employee.getAdress(), тогда запрос времени к базе данных сработает и вернет результаты. Свежий вызов базы данных.

9 голосов
/ 09 января 2014

На языке непрофессионала это похоже на приготовление торта, и вам понадобится 5-10 ингредиентов из холодильника.У вас есть два варианта: взять все ингредиенты из холодильника и положить их на кухонную платформу, или принести нужный вам предмет, когда вам нужно.

Аналогично, при быстрой загрузке вы получаете всю информацию о бобе и связанных с ним классах.(не отношение «ребенок» или «есть», но есть отношение, т. е. в торте есть мука, есть молоко, есть сливки и т. д.), а в случае ленивой загрузки сначала вы приводите только его идентификатор и значения, полученные из одной таблицы (необходимые ингредиентычто сначала вам понадобится в миске на случай пирога).Вся информация, поступающая из других таблиц, будет извлекаться по мере необходимости / использования.

8 голосов
/ 03 февраля 2010

Ленивая загрузка? Ну, это просто означает, что дочерние записи выбираются не сразу, а автоматически, как только вы пытаетесь получить к ним доступ.

3 голосов
/ 18 марта 2011

Параметр Lazy решает, следует ли загружать дочерние объекты при загрузке родительского объекта. Вам необходимо сделать этот параметр соответствующим файлом отображения гибернации родительского класса. Lazy = true (означает не загружать дочерний объект). По умолчанию отложенная загрузка дочернего объекта объекты это правда. Это гарантирует, что дочерние объекты не загружаются, если они явно не вызваны в приложении путем вызова метода getChild () для parent. В этом случае hibernate выдает новый вызов базы данных, чтобы загрузить дочерний объект, когда getChild () фактически вызывается для Parent object.But в некоторых случаях вам нужно загрузить дочерние объекты при загрузке parent. Просто сделайте lazy = false, и hibernate загрузит дочерний элемент, когда родительский элемент загружен из базы данных. Exampleslazy = true (по умолчанию) Адрес дочернего элемента класса User можно сделать ленивым, если он не требуется часто. объект Author для объекта Book parent всякий раз, когда вы имеете дело с книгой для интернет-магазина книг.

2 голосов
/ 03 февраля 2010

Ленивая загрузка - это шаблон проектирования обычно используется в компьютерном программировании отложить инициализацию объекта до точки, в которой это необходимо. Это может способствовать эффективности в работа программы, если правильно и правильно используется

Википедии

Ссылка Ленивая загрузка с hibernate.org

1 голос
/ 16 декабря 2015

Ну, это просто означает загрузку данных, которые вам нужны в настоящее время, вместо загрузки сразу всей совокупности данных, которые вы не будете использовать сейчас. Тем самым ускоряя загрузку приложения быстрее обычного.

...