Разница между JOIN и JOIN FETCH в спящем режиме



пожалуйста, помогите мне понять, где использовать обычный JOIN и где JOIN FETCH.



например, если у нас есть эти два запроса



FROM Employee emp
JOIN emp.department dep


и



FROM Employee emp
JOIN FETCH emp.department dep


есть ли разница между ними? Если да, то какой из них использовать, когда?

1041   4  

4 ответов:

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

но разница в том, что в первом запросе вы возвращаете только сотрудников для спящего режима. Во втором запросе вы возвращаете Employes и все связанные отделы.

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

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

Я рекомендую прочитать эту ссылку, Если вам нужно применить некоторые условия WHERE (что вам, вероятно, понадобится):Как правильно выразить JPQL "join fetch" с предложением "where" в качестве JPA 2 CriteriaQuery?

обновление

если вы не используете fetch и Отделы продолжают возвращаться, потому что ваше сопоставление между сотрудником и отделом (a @OneToMany) установлены с FetchType.EAGER. В этом случае любой HQL (с fetch или нет) запросов с FROM Employee привезут все отделы. Помните, что все отображения *ToOne (@ManyToOne и @OneToOne) жаждут по умолчанию.

на этой ссылке Я уже упоминал в комментарии, прочитайте эту часть:

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

это " JOIN FETCH" будет иметь это эффект, если у вас есть (fetch = FetchType.LAZY) свойство для коллекции внутри сущности (пример ниже).

и это только эффект метод "когда запрос должен произойти". И вы также должны знать этой:

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

когда извлекается ассоциация -- > ваш тип "FETCH"

как это за уши --> объединить/выбрать/выбрать/партии

в вашем случае FETCH будет иметь эффект только в том случае, если у вас есть отдел как набор внутри сотрудника, что-то вроде этого в сущности:

@OneToMany(fetch = FetchType.LAZY)
private Set<Department> department;

при использовании

FROM Employee emp
JOIN FETCH emp.department dep

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

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

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

используйте fetch, когда:

  • больших нужны коллекция / набор внутри этой сущности, которую вы собираетесь получить

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

  • вам может понадобиться эта коллекция, когда у вас нет доступа к ней(за пределами на транзакционные метод/класс)

Если у вас есть @oneToOne mapping установлен в FetchType.LAZY и вы используете второй запрос (потому что вам нужно, чтобы объекты отдела загружались как часть объектов сотрудников) что Hibernate будет делать, он будет выдавать запросы для извлечения объектов отдела для каждого отдельного объекта сотрудника, который он извлекает из БД. Позже в коде вы можете получить доступ к объектам отдела через Employee to Department single-valued association и Hibernate не будет выдавать запрос на извлечение объекта отдела для данного сотрудника. Помните, что Hibernate по-прежнему выдает запросы, равные количеству сотрудников, которых он получил. Hibernate будет выдавать одинаковое количество запросов в обоих вышеуказанных запросах, если вы хотите получить доступ к объектам отдела всех объектов сотрудников

Dherik : я не уверен в том, что вы говорите, когда вы не используете fetch результат будет типа:List<Object[ ]> что означает список таблиц объектов, а не список сотрудников.

Object[0] refers an Employee entity 
Object[1] refers a Departement entity 

когда вы используете fetch, есть только один выбор, и результатом является список сотрудников List<Employee> содержащий список отделов. Он переопределяет ленивое объявление сущности.

Comments

    Ничего не найдено.