Статьи

Как выбрать POJO с помощью CriteriaQuery

Criteria API предоставляет безопасный для типов способ программного определения запросов. Как и в JPQL, вы можете использовать его для выбора набора атрибутов сущности и сопоставления каждой записи набора результатов с простым старым Java-объектом (POJO).

Criteria API поддерживает тот же набор функций, что и JPQL, и я показываю в своей новой книге Hibernate Tips — более 70 решений общих проблем Hibernate, как вы можете использовать его для реализации различных вариантов использования. Это кулинарная книга Hibernate с более чем 70 готовыми рецептами для таких тем, как базовые и расширенные сопоставления, ведение журналов, поддержка Java 8, кэширование и статически и динамически определяемые запросы. Вы можете получить его на этой неделе на Amazon по специальной стартовой цене всего в $ 2,99.

Давайте посмотрим на один из рецептов, включенных в книгу. Он использует Criteria API для программного определения запроса, который выбирает набор столбцов базы данных и возвращает их как POJO. Чтобы получить максимальную отдачу от этого поста, вы уже должны быть знакомы с основными понятиями Hibernate .


Как выбрать POJO с помощью CriteriaQuery

проблема

JPQL поддерживает выражения конструктора для выбора POJO вместо сущностей или скалярных значений. Могу ли я сделать то же самое с Criteria API?

Решение

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

 public class AuthorValue { private String firstName; private String lastName; public AuthorValue(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } ... } 

Определение CriteriaQuery следует тому же подходу, который используется для выбора объектов.

Сначала вам нужно получить экземпляр CriteriaBuilder из EntityManager . Это фабричный класс, который помогает вам определять различные части вашего запроса, такие как параметры связывания, вызовы функций и предикаты.

Затем вы создаете экземпляр CriteriaQuery который является корнем графа объектов, представляющего ваш запрос. Я рекомендую createQuery тип возврата вашего запроса в качестве параметра метода createQuery . Он создает типизированный экземпляр интерфейса CriteriaQuery . Я хочу выбрать объекты AuthorValue в этом примере и, следовательно, предоставить AuthorValue.class в качестве параметра.

На следующем шаге вы определяете предложение FROM запроса. В этом примере я использую сущность Author в качестве корня запроса.

Затем вы можете определить проекцию вашего запроса. В этом примере это вызов конструктора AuthorValue . Метод construct CriteriaBuilder позволяет вам определять вызовы конструктора. Вызовите этот метод, используя класс, который Hibernate создает в качестве первого параметра, и необязательный список Selections , которые используются в качестве параметров конструктора.

В этом примере я использую класс метамодели JPA Author_ для ссылки на атрибуты firstName и lastName объекта Author . Если вы не знакомы с метамоделью JPA, взгляните на совет Hibernate Как ссылаться на атрибуты сущностей безопасным для типов способом, который обеспечивает удобный и безопасный для ссылок способ ссылаться на атрибуты сущностей.

Определение WHERE является необязательным. Если вы хотите выбрать все записи из базы данных, вы можете пропустить этот блок и выполнить свой запрос. Вот что я делаю в этом примере. Вы можете увидеть пример определения WHERE в разделе Как выбрать объекты с главой CriteriaQuery.

 CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<AuthorValue> q = cb.createQuery(AuthorValue.class); Root<Author> root = q.from(Author.class); q.select( cb.construct( AuthorValue.class, root.get(Author_.firstName), root.get(Author_.lastName))); 

Это все, что вам нужно сделать, чтобы определить CriteriaQuery . Теперь вы можете выполнить его в два этапа. Сначала вам нужно вызвать метод createQuery EntityManager с вашим CriteriaQuery . Этот вызов метода возвращает тот же интерфейс TypedQuery который используется в ваших запросах JPQL. Вы можете использовать его, чтобы установить значения параметров привязки или разбить результат запроса на страницы. Я не использую никаких параметров привязки в этом примере и, следовательно, могу пропустить эту часть. На последнем этапе вам нужно вызвать метод TypedQuery интерфейсе TypedQuery чтобы выполнить запрос и получить List объектов AuthorValue .

 TypedQuery<AuthorValue> query = em.createQuery(q); List<AuthorValue> authors = query.getResultList(); 

Когда я создал запрос, я ссылался на атрибуты firstName и lastName в определении вызова конструктора. Как видно из следующих сообщений журнала, Hibernate использовал эти ссылки для создания запроса SQL, который выбирает столбцы firstName и lastName из таблицы Author .

 13:43:09,884 DEBUG [org.hibernate.SQL] - select author0_.firstName as col_0_0_, author0_.lastName as col_1_0_ from Author author0_ 

Исходный код

Вы можете найти ссылку на скачивание проекта с исполняемыми тестовыми примерами для этой подсказки Hibernate в книге .

Учить больше

Если вы не хотите создавать POJO для представления результата запроса, вы также можете выбрать набор скалярных значений . Я покажу вам, как это сделать, в главе Как выбрать несколько скалярных значений в CriteriaQuery .

И если вы хотите использовать Criteria API в своем проекте, вы также должны взглянуть на метамодель JPA . Он предоставляет отличный способ создания запросов безопасным для типов способом. Я покажу вам, как использовать и генерировать необходимые классы в главе Как ссылаться на атрибуты сущности безопасным для типов способом .


С помощью CriteriaQuery легко получить POJO из Hibernate

Резюме

API Criteria предоставляет безопасную опцию для программного определения запросов. Как вы видели в отрывке из книги, вы можете использовать его, чтобы выбрать набор столбцов базы данных и позволить Hibernate сопоставить каждую запись набора результатов с POJO.

Получить больше рецептов, как это в моей новой книге Hibernate Советы: более 70 решений общих проблем Hibernate . Он дает вам более 70 готовых рецептов для таких тем, как базовые и расширенные отображения, ведение журналов, поддержка Java 8, кэширование и статически и динамически определяемые запросы. Всего за несколько дней вы можете получить электронную книгу за 2,99 долларов и мягкую обложку за 12,99 долларов .