JPA и Hibernate – критерии против JPQL или HQL

Каковы плюсы и минусы использования критериев или HQL ? API-интерфейс Criteria – хороший объектно-ориентированный способ выражения запросов в Hibernate, но иногда запросы Criteria Quar сложнее понять / построить, чем HQL.

Когда вы используете критерии и когда HQL? Что вы предпочитаете в случаях использования? Или это просто вопрос вкуса?

    Я предпочитаю запросы Criteria для динамических запросов. Например, намного проще добавить некоторый заказ динамически или оставить некоторые части (например, ограничения) в зависимости от некоторого параметра.

    С другой стороны, я использую HQL для статических и сложных запросов, потому что намного легче понять / прочитать HQL. Кроме того, я думаю, что HQL является более мощным, например, для разных типов соединений.

    Существует разница в показателях производительности между HQL и criteriaQuery, каждый раз, когда вы запускаете запрос с помощью метода критерияQuery, он создает новый псевдоним для имени таблицы, который не отражается в последнем запрошенном кеше для любой БД. Это приводит к накладным расходам на сбор сгенерированного SQL, что требует больше времени для выполнения.

    Что касается страtagsй отбора (http://www.hibernate.org/315.html)

    • Критерии соответствуют настройкам лень в ваших сопоставлениях и гарантируют загрузку загружаемого загружаемого материала. Это означает, что один запрос Критерии может привести к нескольким SQL-операторам SELECT SELECT, чтобы получить подграф со всеми нелазными сопоставленными ассоциациями и коллекциями. Если вы хотите изменить «как» и даже «что», используйте setFetchMode (), чтобы включить или отключить выбор внешнего соединения для определенной коллекции или ассоциации. Критические запросы также полностью учитывают страtagsю выборки (join vs select vs subselect).
    • HQL уважает настройки лень в ваших сопоставлениях и гарантирует загрузку загружаемого загружаемого файла. Это означает, что один запрос HQL может привести к нескольким SQL-операторам SELECT SELECT, чтобы получить подграф со всеми нелазными сопоставленными ассоциациями и коллекциями. Если вы хотите изменить «как» и даже «что», используйте LEFT JOIN FETCH, чтобы включить выборку внешнего соединения для конкретной коллекции или обнулить ассоциацию «один-два-один» или «один-к-одному» или использовать JOIN FETCH для включения внутренняя assembly для нечетной ассоциации «много-к-одному» или «один-к-одному». Запросы HQL не учитывают fetch = “join”, определенные в документе сопоставления.

    Критерии – объектно-ориентированный API, а HQL – конкатенация строк. Это означает, что все преимущества объектно-ориентированного подхода:

    1. При прочих равных условиях версия OO несколько менее подвержена ошибкам. Любая старая строка может быть добавлена ​​в запрос HQL, тогда как только действительные объекты Criteria могут превратить ее в дерево критериев. Эффективно, classы Критерии более ограничены.
    2. С автозаполнением OO становится более доступным (и, следовательно, проще для меня, по крайней мере, для меня). Вы не обязательно должны помнить, какие части запроса идут туда, где; IDE может помочь вам
    3. Вам также не нужно запоминать детали синтаксиса (например, какие символы идут туда). Все, что вам нужно знать, – это вызов методов и создание объектов.

    Поскольку HQL очень похож на SQL (который большинство разработчиков уже знает очень хорошо), то эти аргументы «не нужно помнить» не имеют такого большого веса. Если бы HQL был более разным, тогда это было бы более importatnt.

    Обычно я использую критерии, когда я не знаю, какие входы будут использоваться для каких fragmentов данных. Как в форме поиска, где пользователь может ввести любое из 1 до 50 элементов, и я не знаю, что они будут искать. Очень просто добавить дополнительные критерии, поскольку я проверяю, что ищет пользователь. Я думаю, было бы немного сложнее поставить HQL-запрос в этом случае. HQL замечательный, хотя, когда я точно знаю, чего хочу.

    HQL намного легче читать, проще отлаживать с помощью таких инструментов, как плагин Eclipse Hibernate, и проще вести журнал. Запросы критериев лучше для построения динамических запросов, где во время выполнения определяется большая часть поведения. Если вы не знаете SQL, я мог бы понять, используя запросы Criteria, но в целом я предпочитаю HQL, если я знаю, что мне нужно.

    Критерии – единственный способ указать естественные ключевые поисковые запросы, которые используют специальную оптимизацию в кэше запросов второго уровня. HQL не имеет никакого способа указать необходимый подсказку.

    Вы можете найти дополнительную информацию здесь:

    Критерии Api – одна из хороших концепций Hibernate. по моему мнению, это несколько моментов, по которым мы можем сделать разницу между HQL и критериями Api

    1. HQL выполняет как выборочные, так и неотселируемые операции с данными, но критерии предназначены только для выбора данных, мы не можем выполнять операции без выбора с использованием критериев.
    2. HQL подходит для выполнения статических запросов, где в качестве критериев подходит для выполнения динамических запросов
    3. HQL не поддерживает концепцию разбивки на страницы , но мы можем достичь разбивки на страницы с помощью критериев.
    4. Критерии, используемые для выполнения большего количества времени, чем HQL.
    5. С критериями мы в безопасности с SQL Injection из-за его динамического генерации запросов, но в HQL, поскольку ваши запросы либо фиксированы, либо параметризованы, нет надежды на SQL Injection

    Для меня Критерии довольно легко понять и сделать динамические запросы. Но недостаток, о котором я говорю до сих пор, заключается в том, что он загружает все отношения между несколькими и т. Д., Потому что у нас есть только три типа FetchModes, то есть Select, Proxy и Default, и во всех этих случаях он загружает много-один (может быть, я ошибаюсь, если так помогает меня вне :))

    Вторая проблема с критериями заключается в том, что она загружает полный объект, т. Е. Если я хочу просто загрузить EmpName сотрудника, он не придумает этого, он бы придумал полный объект Employee, и я могу получить EmpName из-за этого, это действительно плохо работает в отчетности . где, поскольку HQL просто загружает (не загружает ассоциацию / отношения), что вы хотите увеличить производительность во много раз.

    Одна из характеристик Criteria заключается в том, что она будет безопасна от SQL Injection из-за ее генерации динамических запросов, где, как и в HQL, поскольку запросы ur являются либо фиксированными, либо параметризированными, поэтому не являются безопасными для SQL Injection.

    Также, если вы пишете HQL в файлах urpx.cs, тогда вы тесно связаны с ур DAL.

    В целом, мой вывод состоит в том, что есть места, где u не может жить без HQL-подобных отчетов, поэтому используйте их иначе. Критерии легче управлять.

    Чтобы использовать лучшее из обоих миров, expressивность и краткость HQL и динамический характер критериев рассматривают использование Querydsl .

    Querydsl поддерживает JPA / Hibernate, JDO, SQL и коллекции.

    Я поддерживаю Querydsl, поэтому этот ответ предвзятый.

    Для меня самая большая победа в Criteria – это пример API, где вы можете передать объект, а hibernate будет строить запрос на основе этих свойств объекта.

    Кроме того, критерии API имеют свои причуды (я считаю, что команда спящего режима перерабатывает api), например:

    • критерий. createAlias ​​(«obj») заставляет внутреннее соединение вместо возможного внешнего соединения
    • вы не можете создать один и тот же псевдоним два раза
    • в некоторых sql-предложениях нет простого сопоставления критериев (например, подзаголовка)
    • и т.п.

    Я обычно использую HQL, когда мне нужны запросы, похожие на sql (delete from Users, где status = ‘blocked’), и я склонен использовать критерии, когда я не хочу использовать добавление строк.

    Другим преимуществом HQL является то, что вы можете определить все свои запросы перед рукой и даже вывести их на экран в файл или так далее.

    Критерии api предоставляют одну отличную функцию, которую не обеспечивают SQL или HQL. то есть. он позволяет проверять время выполнения запроса.

    Criteria API лучше подходит для динамически генерируемых запросов, когда фильтры запросов динамически применяются во время выполнения. Поэтому, чтобы предотвратить атаки SQL Injection при построении динамических запросов, Criteria API – очень хороший выбор.

    Запросы критериев менее выразительны, и вы можете легко получить очень сложный и неэффективный SQL-запрос . Я однажды присоединился к крупному корпоративному приложению, где Criteria API был методом запросов по умолчанию, и даже обширный обзор кода не смог справиться с ужасом, не зная, какие SQL-запросы мы собираемся закончить.

    JPQL или HQL гораздо более выразительны, и гораздо проще предсказать связанный с ним SQL-запрос. Также гораздо проще просмотреть свои запросы HQL, чем критерии.

    Большинство случаев использования запросов запросов не требуют динамических предложений where, чтобы вы могли реализовать большинство запросов с помощью JPQL, оставив критерии для динамических.

    Стоит отметить, что выбор объектов с JPQL или Criteria API имеет смысл, если вам нужно их модифицировать. В противном случае проекция DTO будет работать лучше. Ознакомьтесь с этой статьей для получения дополнительной информации .

    Мы использовали главным образом критерии в нашем приложении в начале, но после того, как он был заменен на HQL из-за проблем с производительностью.
    В основном мы используем очень сложные запросы с несколькими объединениями, что приводит к нескольким запросам в критериях, но очень оптимизировано в HQL.
    Дело в том, что мы используем только несколько пропозиций для конкретного объекта, а не для полных объектов. С критериями проблема заключалась также в конкатенации строк.
    Скажем, если вам нужно отображать имя и фамилию пользователя в HQL, это довольно просто (name || ' ' || surname) но в Crteria это невозможно.
    Чтобы преодолеть это, мы использовали ResultTransormers, где были методы, в которых такая конкатенация была реализована для необходимого результата.
    Сегодня мы в основном используем HQL следующим образом:

     String hql = "select " + "c.uuid as uuid," + "c.name as name," + "c.objective as objective," + "c.startDate as startDate," + "c.endDate as endDate," + "c.description as description," + "s.status as status," + "t.type as type " + "from " + Campaign.class.getName() + " c " + "left join c.type t " + "left join c.status s"; Query query = hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql); query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); return query.list(); 

    поэтому в нашем случае возвращаемые записи являются картами необходимых свойств.

    • HQL должен выполнять операции select и non-select для данных, но критерии предназначены только для выбора данных, мы не можем выполнять операции без выбора с использованием критериев
    • HQL подходит для выполнения статических запросов, где в качестве критериев подходит для выполнения динамических запросов
    • HQL не поддерживает концепцию разбивки на страницы, но мы можем достичь разбивки на страницы с помощью критериев
    • Критерии, используемые для выполнения большего количества времени, а затем HQL
    • С критериями мы в безопасности с SQL Injection из-за его динамического генерации запросов, но в HQL, поскольку ваши запросы либо фиксированы, либо параметризованы, нет надежды на SQL Injection.

    источник

    Критерий запроса для динамического построения мы можем построить запрос на основе наших входов. В случае запроса Hql статический запрос после построения мы не можем изменить структуру запроса.

    Я не хочу пинать здесь мертвую лошадь, но важно отметить, что запросы Criteria теперь устарели. Используйте HQL.

    Я также предпочитаю запросы критериев для динамических запросов. Но я предпочитаю hql для запросов на удаление, например, если удалить все записи из дочерней таблицы для родительского идентификатора «xyz», это легко достигается с помощью HQL, но для критериев API сначала нужно запустить n число запросов на удаление, где n – число дочерних табличные записи.

    Большинство ответов здесь вводят в заблуждение и упоминают, что Criteria Queries медленнее, чем HQL , что на самом деле не так.

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

    А также с Query Query вы получаете объектно-ориентированный элемент управления, которого нет в HQL .

    Для получения дополнительной информации прочтите этот ответ здесь .

    Есть и другой способ. Я закончил создание парсера HQL на основе синтаксиса спящего режима, поэтому сначала проанализировал HQL, затем он мог динамически вводить динамические параметры или автоматически добавлять некоторые общие фильтры для запросов HQL. Он отлично работает!

    Этот пост довольно старый. Большинство ответов говорят о критериях гибернации, а не о критериях JPA. JPA 2.1 добавил CriteriaDelete / CriteriaUpdate и EntityGraph, который контролирует, что именно нужно извлечь. Критерии API лучше, так как Java является OO. Вот почему JPA создается. Когда JPQL будет скомпилирован, он будет переведен в дерево AST (модель OO) до перевода на SQL.

    HQL может вызвать проблемы безопасности, такие как SQL-инъекция.

    Interesting Posts

    Free Rest API для получения текущего времени в виде строки (часовой пояс неактуальен)

    Как обновить прошивку моего iPod Touch в Ubuntu?

    Преобразование целого числа в массив цифр

    Как удалить файлы старше X часов

    Как реализована длина в массивах Java?

    Как сравнить свойство char в EL

    «Обнаружена ошибка с обнаруженным дефектом» (NTLM не Kerberos) с Kerberos / Spring Security / IE / Active Directory

    Spring JPA выбирает определенные столбцы

    Intel Rapid Storage отказывается работать (без кнопки в утилите SRT)

    Какие маршрутизаторы вы предпочитаете для DD-WRT или OpenWRT?

    Безопасно ли использовать ноутбук без батареи?

    Как связать использование GCC без -l или пути hardcoding для библиотеки, которая не соответствует соглашению об именах libNAME.so?

    Разрешить пользователям определенной группы запускать команду без sudo

    проблема с базой данных sqlite, нет такой таблицы:

    Как разрабатывать плагины для собственного браузера для Android

    Давайте будем гением компьютера.