2010-02-03 4 views

ответ

240

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

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

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

+0

Хорошее объяснение –

+75

какой фокус !! parent.getChildren() размер(). +1 –

+3

Альтернативно Hibernate.initialize (parent.getChildren()) следует использовать – HakunaMatata

5

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

2

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

Википедия

Связь Lazy Loading из hibernate.org

66

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

pattern как это:

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

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

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

E.g.

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(); 
} 
+0

У меня такой же случай, и спящий режим выдает исключение при доступе к набору children = parent.getChildren(); , есть ли дополнительная конфигурация, чтобы сделать это. – bmscomp

22

Мартин Фаулер определяет Lazy Load модели в Patterns of Enterprise Application Architecture как таковые:

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

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

Это не шаблон, характерный для доступа к данным и Hibernate, но он особенно полезен в таких полях, и Hibernate поддерживает ленивую загрузку ассоциаций «один-ко-многим» и одноточечных ассоциаций (от одного до одного и от нескольких до -one) также при определенных условиях. Lazy-взаимодействие обсуждается более подробно в Chapter 19 справочной документации Hibernate 3.0.

0

Hiberante поддерживает функцию ленивой инициализации как для объектов, так и для коллекций. Двигатель Hibernate загружает только те объекты, которые мы запрашиваем, не относится к другим объектам или коллекциям.

ленивые = «ложь» при загрузке по умолчанию инициализации упоминания для единственного ребенка lazy.in случае верно, что является родитель загрузка не поддерживает ребенок

3

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

0

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

12

Bydefault lazy loading is true.Lazy загрузка означает, что при выполнении запроса select он не попадет в базу данных. Он будет ждать функции getter. Тогда, когда мы этого потребуем, он будет извлекаться из базы данных. например: Вы родитель, у которого есть ребенок с большим количеством игрушек. Но текущая проблема - всякий раз, когда вы называете его (мы предполагаем, что у вас есть мальчик), он приходит к вам со всеми своими игрушками. Теперь это проблема, потому что вы не хотите, чтобы он носил его игрушки все время. Итак, будучи родителем логического обоснования, вы идете прямо вперед и определяете игрушки ребенка как ЛАЗИ. Теперь, когда вы его называете, он просто приходит к вам без его игрушек.

+3

Это хорошая аналогия. – Siddhartha

7

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

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

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

Пример: Если у вас ТАБЛИЦА? EMPLOYEE сопоставлен с объектом Employee и содержит набор объектов Address. Родитель Класс: класс Employee, Детский класс: Адрес Класс

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 этот дочерний объект времени также загружается и устанавливается метод setAddresss(). Если вы вызываете employee.getAdress(), тогда загружаются данные returns.No новый вызов базы данных.

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

+0

Сотрудник и адрес не имеют отношения родитель-ребенок в этом сценарии. Это ** 'имеет-a' отношение **! – Ram

+0

Это агрегирование не наследование. – Rishi

1

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

Ленивая инициализация имеет две цели: задержку дорогостоящую операция, пока это не абсолютно необходимо магазина результат этой дорогостоящей операции, так что вам не нужно будет повторять его снова

5

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

Надеется, что это помогает :)

0

Ленивой загрузка позволяет отложить извлечение ассоциации или иметь больший контроль над кокетливой стратегией.

Когда вы используете загрузку EAGER, вы определяете план глобальной выборки, который нельзя переопределить во время запроса, то есть вы ограничены решением, которое вы приняли при разработке модели объекта. EAGER fetching is a code smell, так как стратегия выборки - это политика времени запроса и может отличаться от случая использования бизнеса другим.

fetching strategy - очень важный аспект, так как слишком большая выборка EAGER может вызвать серьезные проблемы, связанные с производительностью.

0

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

0

Удивительно, но ни один из ответов не говорит о том, как это достигается за спящий режим за экранами.

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


1. Байт-код приборостроение:

Усиливает определение базового класса с Hibernate hooks перехватывать все вызовы к этому объекту сущности.

сделано либо во время компиляции или запуска [нагрузки] время

1.1 время компиляции

  • сообщение компиляции продолжительность работы

  • В основном с помощью Maven/ANT плагинов

1.2 Время работы

  • Если нет времени компиляции приборов не будет сделано, это создается во время выполнения Использование библиотеки javassist

2. Proxies

Объект объекта, который Hibernate возвращает полномочны реального типа.

Смотрите также: Javassist. What is the main idea and where real use?