Вопрос

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

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

Это было полезно?

Решение

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

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

Другие советы

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

Что касается стратегий выборки [http://www.hibernate.org/315.html]

  • Criterions учитывает настройки лени в ваших сопоставлениях и гарантирует, что то, что вы хотите загрузить, будет загружено.Это означает, что один запрос критериев может привести к появлению нескольких операторов SQL immediate SELECT для извлечения подграфа со всеми неповторяющимися сопоставленными ассоциациями и коллекциями.Если вы хотите изменить "как" и даже "что", используйте setFetchMode(), чтобы включить или отключить выборку внешнего соединения для определенной коллекции или ассоциации.Запросы критериев также полностью соответствуют стратегии выборки (join vs select vs subselect).
  • HQL уважает настройки лени в ваших сопоставлениях и гарантирует, что то, что вы хотите загрузить, будет загружено.Это означает, что один запрос HQL может привести к нескольким операторам SQL immediate SELECT для извлечения подграфа со всеми не-ленивыми сопоставленными ассоциациями и коллекциями.Если вы хотите изменить "как" и даже "что", используйте выборку по ЛЕВОМУ соединению, чтобы включить выборку по внешнему соединению для определенной коллекции или ассоциации "многие к одному" или "один к одному" с возможностью обнуления, или выборку по внутреннему соединению, чтобы включить выборку по внутреннему соединению для ненулевой ассоциации "многие к одному" или "один к одному".Запросы HQL не учитывают никаких fetch="join", определенных в документе сопоставления.

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

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

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

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

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

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

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

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

<Ол>
  • HQL должен выполнять как операции выбора, так и выборки без данных, но Критерии предназначены только для выбора данных, мы не можем выполнять операции без выбора, используя критерии.
  • HQL подходит для выполнения статических запросов, а критерий подходит для выполнения динамических запросов
  • HQL не поддерживает концепцию нумерации страниц , но мы можем добиться нумерации страниц с помощью критериев.
  • Критерии раньше выполнялись дольше, чем HQL.
  • С критериями мы безопасны с SQL-инъекцией из-за его динамической генерации запросов, но в HQL, поскольку ваши запросы являются либо фиксированными, либо параметризованными, нет никакой защиты от SQL-инъекции
  • Для меня Критерии довольно легко понять и делать динамические запросы. Но недостаток, который я до сих пор говорю, заключается в том, что он загружает все отношения многие-один и т. Д., Потому что у нас есть только три типа FetchModes, то есть Select, Proxy и Default, и во всех этих случаях он загружает многие-один (может быть, я ошибаюсь, если это поможет меня нет :))

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

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

    Кроме того, если вы пишете HQL в файлах ur aspx.cs, то вы тесно связаны с вашим DAL.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Вначале мы использовали главным образом критерии в нашем приложении, но после его замены на HQL из-за проблем с производительностью.
    В основном мы используем очень сложные запросы с несколькими объединениями, что приводит к нескольким запросам в критериях, но очень оптимизировано в HQL.
    Дело в том, что мы используем только несколько свойств на конкретном объекте, а не на полных объектах. С критериями проблема заключалась также в конкатенации строк.
    Допустим, если вам нужно отобразить имя и фамилию пользователя в HQL, это довольно просто (name || '' || фамилия) , но в 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 с данными, но Criteria предназначен только для выбора данных, мы не можем выполнять операции non-select с использованием criteria
    • HQL подходит для выполнения статических запросов, где as Criteria подходит для выполнения динамических запросов
    • HQL не поддерживает концепцию разбивки на страницы, но мы можем добиться разбивки на страницы с помощью критериев
    • Критерии, выполнение которых раньше занимало больше времени, чем HQL
    • С Criteria мы безопасны при SQL-инъекции из-за ее динамической генерации запросов, но в HQL, поскольку ваши запросы либо фиксированы, либо параметризованы, защиты от SQL-инъекции нет.

    Источник

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

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

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

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

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

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

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

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

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

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top