«1. Обзор
В этом руководстве мы обсудим, как использовать классы статической метамодели JPA при написании запросов критериев в Hibernate.
Нам потребуется базовое понимание API-интерфейсов запросов критериев в Hibernate, поэтому, если необходимо, ознакомьтесь с нашим руководством по запросам критериев для получения дополнительной информации по этой теме.
2. Почему метамодель JPA?
Часто, когда мы пишем критерий запроса, нам нужно ссылаться на классы сущностей и их атрибуты.
Теперь один из способов сделать это — указать имена атрибутов в виде строк. Но, это имеет несколько недостатков.
Во-первых, нам нужно искать имена атрибутов сущности. И, если имя столбца будет изменено позже в жизненном цикле проекта, нам придется реорганизовать каждый запрос, в котором используется это имя.
Метамодель JPA была введена сообществом, чтобы избежать этих недостатков и обеспечить статический доступ к метаданным классов управляемых объектов.
3. Класс сущностей
Давайте рассмотрим сценарий, в котором мы создаем систему управления студенческим порталом для одного из наших клиентов, и возникает требование предоставить функциональность поиска для студентов на основе их года выпуска.
Во-первых, давайте посмотрим на наш класс Student:
@Entity
@Table(name = "students")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "grad_year")
private int gradYear;
// standard getters and setters
}
4. Генерация классов метамодели JPA
Далее нам нужно сгенерировать классы метамодели, и для этой цели мы будем использовать инструмент генератора метамодели предоставлено JBoss. JBoss — это лишь один из многих инструментов, доступных для создания метамодели. Другие подходящие инструменты включают EclipseLink, OpenJPA и DataNucleus.
Чтобы использовать инструмент JBoss, нам нужно добавить последнюю зависимость в наш файл pom.xml, и инструмент сгенерирует классы метамодели, как только мы запустим команду сборки maven:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.3.7.Final</version>
</dependency>
Обратите внимание, нам нужно добавьте папку target/generated-classes в путь к классам нашей IDE, так как по умолчанию классы будут генерироваться только в этой папке.
5. Классы статической метамодели JPA
В соответствии со спецификацией JPA сгенерированный класс будет находиться в том же пакете, что и соответствующий класс сущности, и будет иметь то же имя с добавленным «_» (подчеркивание) в конце конец. Таким образом, класс метамодели, сгенерированный для класса Student, будет Student_ и будет выглядеть примерно так: ссылки на атрибуты. API запроса критериев предоставляет перегруженные методы, которые принимают ссылки на строки, а также реализации интерфейса атрибутов.
@Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Student.class)
public abstract class Student_ {
public static volatile SingularAttribute<Student, String> firstName;
public static volatile SingularAttribute<Student, String> lastName;
public static volatile SingularAttribute<Student, Integer> id;
public static volatile SingularAttribute<Student, Integer> gradYear;
public static final String FIRST_NAME = "firstName";
public static final String LAST_NAME = "lastName";
public static final String ID = "id";
public static final String GRAD_YEAR = "gradYear";
}
Давайте посмотрим на запрос критериев, который выведет всех студентов, окончивших школу в 2015 году:
Обратите внимание, что мы использовали ссылку Student_.gradYear вместо обычного имени столбца grad_year.
7. Заключение
//session set-up code
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery<Student> criteriaQuery = cb.createQuery(Student.class);
Root<Student> root = criteriaQuery.from(Student.class);
criteriaQuery.select(root).where(cb.equal(root.get(Student_.gradYear), 2015));
Query<Student> query = session.createQuery(criteriaQuery);
List<Student> results = query.getResultList();
В этой быстрой статье мы узнали, как использовать классы статической метамодели и почему они могут быть предпочтительнее традиционного способа использования ссылок на строки, как описано ранее.
Исходный код этого руководства можно найти на Github.
«
The source code of this tutorial can be found over on Github.