2008-10-13 9 views
270

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

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

+0

Правильный ответ будет «зависит от варианта использования». – Hace 2011-01-08 23:22:51

+0

А как насчет [этого инструмента] (https://github.com/knyttl/Maite/wiki/Maite-Persistence)? Он позволяет создавать общие запросы объектным способом: protected Clause select() {return em.select ("DISTINCT i"). From (this.getName(), "i") .joinFetch ("i.locale lf"). } public T findBySlug (String slug) {return (T) this.select() .join ("i.locale l"); .where ("l.slug =?", slug) .fetchSingle(); } – 2012-02-16 10:22:35

+1

Определение мнения, основанного на мнениях, но люди не воспользовались возможностью, чтобы закрыть его ... по сайту FAQ – 2017-05-17 17:22:37

ответ

197

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

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

+7

Кроме того, хотя критерии выглядят немного более безопасными по типу, единственное, что может заставить вас почувствовать безопасное тестирование. – 2013-03-06 05:15:56

+0

Есть ли хорошие примеры, которые показывают, почему в некоторых случаях HQL лучше критериев api? Я прочитал конец одного блога, но ничего не понял. Был бы признателен, если бы вы могли помочь. Благодарю. Ссылка - http://www.javalobby.org/articles/hibernatequery102/ – 2014-06-10 01:23:31

+0

Все вышеперечисленные причины - я также предпочитаю критерии для HQL, потому что это безопаснее для программиста, уменьшая ошибки кодирования - компиляция в строке HQL не проверяется. – nuno 2014-07-31 08:37:35

36

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

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

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

+12

Эти аргументы не содержат воды (относительно HQL). Он не должен включать конкатенацию строк. То, что версия OO менее подвержена ошибкам, необоснованна. Он одинаково склонен к ошибкам, но другого рода. Усилия узнать, какие методы вызывать не так сильно отличаются от того, какие символы вызывать в HQL (я имею в виду, серьезно, мы здесь не решаем PDE). – 2010-10-12 13:42:45

+0

Есть ли хорошие примеры, которые показывают, почему HQL лучше критериев api в некоторых случаях? Я прочитал конец одного блога, но ничего не понял. Был бы признателен, если бы вы могли помочь. Благодарю. Ссылка - http://www.javalobby.org/articles/hibernatequery102/ – 2014-06-10 01:22:54

+1

Запрошенные запросы HQL скомпилированы во время развертывания, и в этот момент обнаружены отсутствующие поля (возможно, для плохих рефакторов?). Я думаю, что это делает код более устойчивым и на самом деле менее подверженным ошибкам, чем критерии. – narduk 2015-07-27 14:10:49

31

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

31

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

+0

Это хороший комментарий. В настоящее время мы создаем очень большие строки HQL для формы поиска, которая содержит много разных объектов через объединения. Выглядит уродливо. Посмотрите, может ли Критерии очистить это. Интересно ... – cbmeeks 2012-11-09 14:08:49

11

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

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

  • критерия.createAlias ​​(«OBJ») вынуждает внутреннее соединение вместо возможного внешнего соединения
  • Вы не можете создавать и тот же псевдоним два раза
  • некоторой SQL оговорка не имеет простые критерии аналога (как подзапрос)
  • и т.д.

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

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

86

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

Что касается стратегии Извлечения [http://www.hibernate.org/315.html]

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

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

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

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

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

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

22

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

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

12

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

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

Я являюсь хранителем Querydsl, поэтому этот ответ предвзято.

7

Мы использовали главным образом критерии в нашем приложении в начале, но после того, как он был заменен на 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(); 

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

9

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

5

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

-3

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

16

Критерии Апи - одна из хороших концепций спящего режима. по моему мнению это те немногие точки, с помощью которого мы можем сделать различие между HQL и Критерии Api

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

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

9

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

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

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

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

Следует отметить, что выбор объектов с помощью JPQL или API критериев имеет смысл, если вам нужно их модифицировать. В противном случае проекция DTO будет работать лучше. Выезд this article for more info.

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

source

-1

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

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

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

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

4

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

0

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