Каковы некоторые примеры из реальной жизни, где JPA2 Criteria API является более предпочтительным? - PullRequest
24 голосов
/ 06 августа 2010

Я взглянул на JPA 2.0 Criteria API, но нашел его слишком громоздким в отличие от Hibernate Criteria.Есть ли веская причина использовать JPA 2.0 Criteria API вместо JPA-QL?Спасибо за ваш совет.

Ответы [ 4 ]

36 голосов
/ 06 августа 2010

Как и API Hibernate Criteria, API JPA 2.0 Criteria особенно удобен для построения запросов динамически для обработки случаев, когда структура запроса меняется в зависимости от условий выполнения.

Но это еще не все. Будучи более многословным, чем Hibernate Criteria API, JPA Criteria API позволяет создавать типов безопасных запросов (если вы используете Metamodel API). Ниже приведен пример:

EntityManager em = ...
QueryBuilder qb = em.getQueryBuilder();
CriteriaQuery<Person> c = qb.createQuery(Person.class);
Root<Person> p = c.from(Person.class);
Predicate condition = qb.gt(p.get(Person_.age), 20);
c.where(condition);
TypedQuery<Person> q = em.createQuery(c); 
List<Person> result = q.getResultList();

В приведенном выше фрагменте, следующее вызовет ошибку компиляции, например:

Predicate condition = qb.gt(p.get(Person_.age, "xyz"));

Если вам интересно, Person_ - это статический, инстанцированный, канонический класс метамодели , соответствующий исходному Person классу сущностей (созданному процессором аннотаций). Он предоставляет строго типизированную альтернативу подходу, основанному на отражении времени выполнения:

Field field = Person.class.getField("age");

Плюсы:

  • Тип безопасности, проверка времени компиляции!
    • Запрещает построение запросов, синтаксически некорректных.
    • Может вызвать ошибку компиляции после рефакторинга.
    • Обеспечивает готовую поддержку автозаполнения
  • Лучше подходит для динамических запросов.

Минусы:

  • Более многословно.
  • Менее читаемый.

В целом я чувствую себя более комфортно с JPQL, но безопасность типов API Criteria является основным отличием от JPQL (а также API Hibernate Criteria).

Смотри также

Похожие ответы

4 голосов
/ 06 августа 2010

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

cq.select(...)
  .where(...)
  .orderBy(...)
  .groupBy(...);

Но при использовании статический запрос предпочитают использовать внешний, поддерживаемый и читаемый файл

<entity-mappings>
    ...
    <named-query name="ORDER">
       <query>
           <![CDATA[
               from
                   Order
           ]]>
       </query>
    </named-query>
    <named-query name="ORDER_WITH_LINE_ITEM">
       <query>
           <![CDATA[
               from
                   Order o
               inner join fetch 
                   o.lineItemList
           ]]>
       </query>
    </named-query>
    ...
</entity-mappings>

Если у вас есть модульное приложение, используйте один xml-файл для каждого модуля следующим образом

br
   com
       ar
           moduleA
               model
                   repository
                       moduleA.xml
           moduleB
               model
                   repository
                       moduleB.xml               
           moduleC
               model
                   repository
                       moduleC.xml

Затем вы определяете свой элемент mappinf-файла

<mapping-file>br/com/ar/moduleA/model/repository/moduleA.xml</mapping-file>
<mapping-file>br/com/ar/moduleB/model/repository/moduleB.xml</mapping-file>
<mapping-file>br/com/ar/moduleC/model/repository/moduleC.xml</mapping-file>
1 голос
/ 06 августа 2010

JPA 2 Критерии могут использоваться в статически типизированной форме, если вы генерируете метамодель сущности. Он более подробный, чем JPQL, но имеет статическую типизацию и напрямую поддерживает построение динамических запросов.

Преимущества статически типизированного языка запросов в том, что вы можете отлавливать больше ошибок во время компиляции, а также можно использовать функции IDE, такие как автозаполнение.

0 голосов
/ 21 апреля 2015

Для меня реальный пример, в котором сияет JPA2, - это когда вам нужно создать запрос на основе ввода от пользователя. Я не говорю об очень простом, где с одним параметром. Я имею в виду, когда вы сделали расширенный поиск в вашем приложении. Тот, который требует объединений, когда определенный параметр заполнен. Вам не нужно объединять ваш HQL или SQL, чтобы включить большой набор параметров, дополнительных объединений и функций. Пользовательский SQL требует много тестов, чтобы доказать, что он работает. Добавление дополнительных параметров поиска в HQL и SQL требует больших переделок, тогда как в JPA это может быть проще.

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