JPA и Hibernate - критерии против JPQL или HQL - PullRequest
283 голосов
/ 13 октября 2008

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

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

Ответы [ 21 ]

205 голосов
/ 13 октября 2008

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

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

90 голосов
/ 04 декабря 2008

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

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

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

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

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

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

34 голосов
/ 14 октября 2008

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

31 голосов
/ 13 октября 2008

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

22 голосов
/ 10 июля 2009

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

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

20 голосов
/ 08 мая 2013

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

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

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

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

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

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

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

12 голосов
/ 12 января 2010

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

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

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

11 голосов
/ 14 октября 2008

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

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

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

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

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

...