Стремление/Ленивая загрузка в спящем режиме

Eager/Lazy Loading In Hibernate

1. Вступление

При работе с ORM выборка / загрузка данных может быть классифицирована на два типа: нетерпеливый и ленивый.

В этой быстрой статье мы собираемся указать на различия и показать, что они могут быть использованы в Hibernate.

2. Maven Зависимости

Чтобы использовать Hibernate, давайте сначала определим основную зависимость в нашемpom.xml:


    org.hibernate
    hibernate-core
    5.2.2.Final

Последнюю версию Hibernate можно найтиhere.

3. Стремительная и ленивая загрузка

Первое, что мы должны обсудить здесь, это то, что ленивая загрузка и нетерпеливая загрузка:

  • Eager Loading - это шаблон проектирования, в котором инициализация данных происходит на месте

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

Давайте посмотрим, как это работает на некоторых примерах:

КлассUserLazy:

@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

}

Класс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

}

ОдинUser может иметь несколькоOrderDetails. In eager loading strategy, if we load the User data, it will also load up all orders associated with it and will store it in a memory.

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

В следующем разделе мы увидим, как приведенный выше пример реализован в Hibernate.

4. Загрузка конфигурации

В этом разделе мы рассмотрим, как мы можем настроить стратегии выборки в Hibernate. Мы будем использовать примеры из предыдущего раздела.

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

fetch = FetchType.LAZY

Для использования Eager Fetching используется следующий параметр:

fetch = FetchType.EAGER

Для настройки нетерпеливой загрузки мы использовали класс-близнецUserLazy под названиемUserEager.

В следующем разделе мы рассмотрим различия между двумя типами выборки.

5. Различия

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

Давайте посмотрим на этот пример:

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

При ленивом подходе к инициализацииorderDetailSet будет инициализирован только тогда, когда он явно вызывается с помощью геттера или какого-либо другого метода, как показано в приведенном выше примере:

UserLazy userLazyLoaded = users.get(3);

Но при активном подходе вUserEager он будет немедленно инициализирован в первой строке приведенного выше примера:

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

Для ленивой загрузки используется прокси-объект и запускается отдельный запрос SQL для загрузкиorderDetailSet.

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

Следующий метод может быть использован для проверки вышеуказанной функциональности:

Hibernate.isInitialized(orderDetailSet);

Теперь важно взглянуть на запросы, которые генерируются в любом случае:

true

Приведенная выше настройка вfetching.hbm.xml показывает сгенерированные запросы SQL. Если вы посмотрите на вывод консоли, то сможете увидеть сгенерированные запросы.

Для отложенной загрузки запрос, который создается для загрузки данныхUser:

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

Однако при активной загрузке мы увидели соединение, выполняемое с помощью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=?

Вышеупомянутый запрос генерируется для всехUsers, в результате чего используется гораздо больше памяти, чем при другом подходе.

6. Преимущества и недостатки

6.1. Ленивая Загрузка

Преимущества:

  • Время начальной загрузки намного меньше, чем при другом подходе

  • Меньшее потребление памяти, чем в другом подходе

Недостатки:

  • Отложенная инициализация может повлиять на производительность в нежелательные моменты

  • В некоторых случаях вам нужно обращаться с лениво инициализированными объектами с особой тщательностью, иначе вы можете получить исключение

6.2. Жадная загрузка:

Преимущества:

  • Отсутствие влияния на производительность при отложенной инициализации

Недостатки:

  • Длительное время начальной загрузки

  • Загрузка слишком большого количества ненужных данных может повлиять на производительность

7. Ленивая загрузка в гибернации

Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation классов.

Hibernate перехватывает вызовы объекта, заменяя его прокси-сервером, полученным из класса объекта. В нашем примере, когда запрошенная информация отсутствует, она будет загружена из базы данных до того, как управление будет передано реализации классаUser.

Следует также отметить, что когда ассоциация представлена ​​как класс коллекции (в приведенных выше примерах она представлена ​​какSet<OrderDetail> orderDetailSet), тогда создается оболочка и заменяется исходной коллекцией.

Чтобы узнать больше о шаблоне проектирования прокси, вы можете обратиться кhere.

8. Заключение

В этой статье мы показали примеры двух основных типов выборки, которые используются в Hibernate.

Для продвинутого уровня экспертизы вы можете посмотреть на официальном сайте Hibernate. Чтобы получить код, обсуждаемый в этой статье, взгляните на этотrepository.