Кэш сеанса сохраняется с помощью взаимосвязанных графиков объектов. По умолчанию, когда Hibernate загружает объекты клиента из базы данных, все связанные объекты заказа загружаются одновременно. Принимая классы клиентов и заказов в качестве примеров, предположим, что иностранная ключ Customer_id таблицы заказов разрешено быть нулевым
Следующий метод Session的find() используется для извлечения всех объектов клиента в базе данных:
List customerLists=session.find("from Customer as c");
При запуске метода find() выше, Hibernate сначала запросит все записи в таблице клиентов, а затем запрашивает таблицу заказов с помощью эталонных отношений на основе идентификатора каждой записи. Hibernate выполнит следующие операторы Select по очереди:
выберите * от клиентов;
выберите * из заказов, где customer_id = 1;
Выберите * из заказов, где customer_id = 2;
Выберите * из заказов, где customer_id = 3;
Выберите * из заказов, где customer_id = 4;
Через вышеупомянутые операторы выбора, Hibernate наконец загружает 4 объекта клиента и 5 объектов заказа, формируя связанный график объекта в памяти.
Hibernate использует политику поиска по умолчанию сейчас при получении объектов заказа, связанных с клиентом. В этой стратегии поиска есть два основных недостатка:
(1) Количество выбранных операторов слишком велик, и частый доступ к базе данных повлияет на производительность поиска. Если вам нужно запросить n объектов клиента, то N+1 выберите оператор запроса. Это классическая проблема N+1 Select. Эта стратегия поиска не использует функцию запроса подключения SQL. Например, приведенные выше 5 выбранных операторов могут быть полностью заполнены следующим оператором 1 SELECT:
Выберите * из клиентов, оставшихся на внешних ордерах
на клиентах.id = orders.customer_id
Приведенный выше оператор SELECT использует левую внешнюю функцию соединения SQL, которая может запросить все записи таблицы клиентов и записи таблицы соответствующих заказов в операторе SELECT.
(2) В ситуациях, когда логика приложения должна только для доступа к объектам клиента, но не заказать объекты, загрузка объектов заказа совершенно не нужна. Эти ненужные объекты заказа тратят много пространства памяти.
Чтобы решить вышеуказанные проблемы, Hibernate предоставляет две другие стратегии поиска: стратегия отсроченного поиска и срочная стратегия поиска подключения. Стратегия отсроченного поиска может избежать избыточной загрузки связанных объектов, к которым приложение не нужно получать. Срочная стратегия извлечения левого внешнего соединения в полной мере использует функцию запроса внешнего соединения SQL и может уменьшить количество выбранных операторов.
Проблемы с производительностью должны рассматриваться при доступе к базам данных. После установления отношений 1 к многим, легендарная проблема N +1 будет возникнуть в запросе.
1) 1 Во многих, в 1 квадрате n объектов можно найти, затем необходимо вывести набор, связанный с n объектами, поэтому исходный запрос SQL становится N +1.
2) Многие по 1. Если вы запросите M-объекты в нескольких сторонах, то будет выведен 1-сторонний объект, соответствующий объектам M, и он также станет M+1.
1) lazy = true, hibernate3 уже дефолт на ленивый = true; Когда Lazy = true, связанный объект не будет запрашиваться немедленно. Действие запроса будет происходить только тогда, когда связанный объект (доступ к его атрибутам, не ID-поля).
2) Кэш 2 уровня. Когда объект гораздо менее обновлен, удален и добавлен, чем запросы, применение кэша уровня 2 не будет бояться проблем N +1, потому что даже если первый запрос будет медленным, удар кэша будет очень быстрым.
Различные решения и разные идеи, но второй просто снова использует n +1.
3) Конечно, вы также можете установить fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))
Выше приведено в краткой дискуссии этой статьи о проблеме Hibernate N+1, и я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!