Що таке ледаче завантаження в сплячому режимі?


178

Що таке ліниве завантаження на Java? Я не розумію цього процесу. Хтось може допомогти мені зрозуміти процес ледачого завантаження?

Відповіді:


268

Скажіть, у вас є батько, а у цього батька є колекція дітей. Зимова сплячка тепер може «ліниво навантажувати» дітей, а це означає, що вона фактично не завантажує всіх дітей при завантаженні батьків. Натомість він завантажує їх, коли просять цього зробити. Ви можете або просити це явно, або, що набагато частіше, сплячий режим завантажує їх автоматично, коли ви намагаєтесь отримати доступ до дитини.

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

Також остерігайтеся проблеми n + 1. Сонник насправді не завантажить усіх дітей, коли ви отримуєте доступ до колекції. Натомість він завантажить кожну дитину окремо. Ітерація над колекцією викликає запит у кожної дитини. Щоб уникнути цього, ви можете підманути сплячку в завантаженні всіх дітей одночасно, наприклад, зателефонувавши parent.getChildren (). Size ().


5
Крім того, слід використовувати Hibernate.initialize (parent.getChildren ())
HakunaMatata

18
Заява "коли ви отримуєте доступ до колекції ... вона буде завантажувати кожну дитину окремо" насправді абсолютно неточна. Це насправді навпаки. Будь-яка дереференція parent.getChildren () призведе до того, що програма Hibernate завантажить усіх дітей у колекції за один db-запит. Якщо ви не використовували той самий спеціальний натяк на ледачий навантажувач. Або, якщо ви не кешуєте колекцію в кеш-пам'яті другого рівня, і пов'язані з ними діти також не кешовані.
Стів Еберсол

О, Переповнення стека - найкращу відповідь можна знайти внизу сторінки ;-)
Піотрек Грицюк

76

"Ледача завантаження" означає, що суб'єкт завантажується лише тоді, коли ви фактично отримаєте доступ до об'єкта вперше .

Картина виглядає так:

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

Це економить витрати на попередню завантаження / попередню заправку всіх об'єктів у великому наборі даних заздалегідь, тоді як вам все-таки не потрібні всі з них.

У сплячому режимі ви можете налаштувати ліниво завантажувати колекцію дочірніх сутностей. Фактична відкладена завантаження потім робляться всередині методів в PersistentSetякому використовується Hibernate «під капотами» , щоб призначити колекцію сутностей як Set.

Напр

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

Мартін Фаулер визначає модель " Ледачий навантаження" в " Шаблонах архітектури корпоративних додатків" таким чином:

Об'єкт, який не містить усіх необхідних даних, але знає, як їх отримати.

Отже, завантажуючи даний об'єкт, ідея полягає в тому, щоб не прагнути завантажувати пов'язані об'єкти, які ви можете не використовувати негайно для економії відповідних витрат на продуктивність. Натомість пов'язані об’єкти (и) завантажуватимуться лише при використанні.

Це не характерний для доступу до даних та сплячого режиму, але він особливо корисний у таких полях, і Hibernate підтримує ліниве завантаження асоціацій один на багато та асоціацій з однією точкою (один на один та багато хто на одного). за певних умов. Ледача взаємодія більш детально розглянута в главі 19 Довідкової документації зі сплячого режиму 3.0.


15

За замовчуванням ледаче завантаження є вірно. Ледаче завантаження означає, що коли виконується запит вибору, він не потрапить у базу даних. Він буде чекати функції getter, тобто коли нам тоді знадобиться, він вийде з бази даних. наприклад: Ви батько, у якого є дитина з великою кількістю іграшок. Але поточне питання - це коли ви телефонуєте йому (ми припускаємо, що у вас є хлопчик), він також приходить до вас з усіма своїми іграшками. Тепер це питання, оскільки ви не хочете, щоб він весь час носив свої іграшки. Отож, будучи батьком, який обгрунтовує, ви йдете прямо вперед і визначаєте іграшки дитини як ЛАЗІ. Тепер, коли ви телефонуєте йому, він просто приходить до вас без своїх іграшок.


11

Ледачий вибір вирішує, чи завантажувати дочірні об’єкти під час завантаження батьківського об'єкта. Вам потрібно виконати це налаштування відповідного сплячого файлу відображення батьківського класу. Lazy = true(означає не завантажувати дитину) За замовчуванням ліниве завантаження дочірніх предметів є істинним.

Це переконайтеся, що дочірні об’єкти не завантажуються, якщо їх явно не викликати в програмі методом виклику getChild()на батьків. У цьому випадку сплячий режим видає новий виклик бази даних для завантаження дитини, коли getChild()він фактично викликається на батьківський об'єкт.

Але в деяких випадках потрібно завантажувати дочірні об’єкти, коли завантажується батьків. Просто переконайтеся, що ледачий = хибний, і сплячий режим буде завантажувати дитину при завантаженні батьків із бази даних.

Приклад: Якщо у вас є таблиця? 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, тоді дочірній об'єкт також завантажується і встановлюється методом setAddresss (). Якщо ви телефонуєте співробітнику.getAdress (), завантажені дані повертаються. Немає свіжого дзвінка з бази даних.

Якщо lazy="true": - Це конфігурація за замовчуванням. Якщо ти не згадуєш, тоді сплячий вважає лінивим = правдою. коли ви завантажуєте об'єкт Співробітник, що дочірній об’єкт Адреса не завантажується. Вам потрібен додатковий виклик до бази даних, щоб отримати об’єкти адреси. Якщо ви зателефонуєте, employee.getAdress()тоді ця запитна база даних запитує і повертає результати. Свіжий дзвінок до бази даних.


Співробітник та адреса не мають стосунку батько-дитина в цьому сценарії. Це стосунки "має-є" !
Рам

Це агрегація, а не спадкування.
Ріші

11

Мовою мирян це так, як ви робите торт, і вам знадобиться 5-10 інгредієнтів з холодильника. У вас є два варіанти, дістаньте всі інгредієнти з холодильника і покладіть його на кухонну платформу або принесіть потрібний вам предмет, коли вам потрібно.

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


8

Ледачий завантаження? Ну, це просто означає, що дочірні записи отримуються не відразу, а автоматично, як тільки ви намагаєтесь отримати доступ до них.


4

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

Коли ви використовуєте EAGER для завантаження, ви визначаєте глобальний план вибору, який неможливо змінити під час запиту, тобто ви обмежені рішенням, яке ви прийняли під час проектування вашої моделі сутності. EAGER вибірка є кодом запах , тому що вибірка стратегія є запитом часу політика і вона може відрізнятися від бізнес - прецеденту до іншого.

Стратегія отримання - це дуже важливий аспект, оскільки занадто велика кількість EAGER може спричинити серйозні проблеми, пов'язані з ефективністю.


3

Налаштування "Ледачий" визначає, чи потрібно завантажувати дочірні об'єкти під час завантаження батьківського об'єкта. Вам потрібно виконати цей параметр відповідному сплячому файлу відображення батьківського класу.Lazy = true (означає не завантажувати дитину) За замовчуванням ліниве завантаження дочірніх об'єктів відповідає дійсності . Переконайтеся, що дочірні об’єкти не завантажуються, якщо вони не явно викликаються в додатку, викликаючи метод getChild () на батьків. У цьому випадку сплячий режим видає новий виклик бази даних для завантаження дитини, коли getChild () фактично викликається на батьківщину object. Але в деяких випадках вам потрібно завантажити дочірні об’єкти під час завантаження батьків. Просто зробіть ледачий = хибний, і сплячий режим буде завантажувати дитину, коли батько завантажується з бази даних. Експрес-приклад = істина (за замовчуванням) Адреса дочірнього класу користувача може бути лінивою, якщо це не потрібно часто.


2

Ледаче завантаження - це модель дизайну, яка зазвичай використовується в комп'ютерному програмуванні для відстрочки ініціалізації об'єкта до тієї точки, в якій це потрібно. Це може сприяти ефективності роботи програми при правильному та належному використанні

Вікіпедія

Посилання ледачого завантаження з hibernate.org


1

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


0

Hiberante підтримує функцію лінивої ініціалізації як для об'єктів, так і для колекцій. Hibernate двигун завантажує лише ті об’єкти, про які ми запитуємо, не містить інших запитів чи колекцій.

lazy = "false" за замовчуванням згадка про ініціалізацію завантаження для єдиної дитини - lazy.in випадок true, який є батьківським, завантаження не підтримує дочірню


0

Параметр "Ледачий" визначає, чи потрібно завантажувати дочірні об'єкти під час завантаження батьківського об'єкта. Вам потрібно виконати цей параметр відповідного сплячого файлу відображення батьківського класу.Lazy = true (означає не завантажувати дитину) За замовчуванням ліниве завантаження дочірніх об'єктів є істинним .


0

Дивно, але жоден з відповідей не говорить про те, як це досягається в сплячку за екранами.

Ледаче завантаження - це модель дизайну, яка ефективно використовується в сплячому режимі з міркувань продуктивності, яка включає наступні методи.


1. Приладобудівний код :

Покращує визначення базового класу за допомогою сплячих гаків для перехоплення всіх викликів до цього об'єкта.

Зроблено або під час компіляції, або час запуску [load]

1.1 Час компіляції

  • Операція часу компіляції

  • Переважно плагінами Maven / Ant

1.2 Час виконання

  • Якщо інструментів часу компіляції не виконано, це створюється під час виконання, використовуючи бібліотеки типу javassist

2. Проксі

Об'єкт сутності, який повертає в режим hibernate, є проксі-сервером реального типу.

Дивіться також: Javassist. Яка основна ідея і де реально використовувати?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.