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

Я хотел бы внести свой вклад в один общий сценарий (в Python 3) и изучить несколько подходов к нему.

Встроенная функция open () принимает либо относительный или абсолютный путь в качестве первого аргумента. Относительный путь трактуется как относительно текущего рабочего каталога , хотя поэтому рекомендуется передать абсолютный путь к файлу.

Проще говоря, если вы запустите файл сценария с в следующем коде не гарантируется, что файл example.txt будет создан в том же каталоге, где находится файл сценария:

with open('example.txt', 'w'):
    pass

Чтобы исправить этот код, нам нужно получить путь к сценарий и сделать его абсолютным. Чтобы гарантировать абсолютный путь, мы просто используем функцию os.path.realpath () . Чтобы получить путь к скрипту, есть несколько общих функций, которые возвращают различные результаты:

  • os.getcwd()
  • os.path.realpath('example.txt')
  • sys.argv[0]
  • __file__

Обе функции os.getcwd () и os.path.realpath () возвращают результаты на основе текущего рабочего каталога . Вообще не то, что мы хотим. Первым элементом списка sys.argv является путь корневого сценария (сценарий, который вы запускаете), независимо от того, вызываете ли вы этот список в самом корневом скрипте или в любой из его модулей. Это может пригодиться в некоторых ситуациях. Переменная __ file __ содержит путь к модулю, из которого он был вызван.


Следующий код правильно создает файл example.txt в том же каталоге, где скрипт находится:

filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')

with open(filepath, 'w'):
    pass

24
задан Joshua Partogi 6 August 2010 в 02:59
поделиться

3 ответа

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

Но это еще не все. Будучи более подробным, чем API критериев Hibernate, API критериев JPA позволяет создавать типизированные запросы (если вы используете 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, но безопасность типов Criteria API является основным отличием от JPQL (а также Hibernate Criteria API).

См. Также

Связанные ответы

36
ответ дан 28 November 2019 в 23:37
поделиться

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-file

<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>
4
ответ дан 28 November 2019 в 23:37
поделиться

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

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

1
ответ дан 28 November 2019 в 23:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: