Рубрики
Без рубрики

Типы запросов JPA

Изучите запросы JPA вместе с их использованием.

Автор оригинала: baeldung.

Типы запросов JPA

1. Обзор

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

2. Настройка

Во-первых, давайте определим ПользовательЕнтность класс, который мы будем использовать для всех примеров в этой статье:

@Table(name = "users")
@Entity
public class UserEntity {

    @Id
    private Long id;
    private String name;
    //Standard constructor, getters and setters.

}

Существует три основных типа запросов JPA:

  • Запрос , написано в синтаксисе Java Persistence Query Language (JP’L)
  • Родной Квери , написанная простым синтаксисом S’L
  • Критерии API Запрос , построено программно с помощью различных методов

Давайте исследуем их.

3. Запрос

A запрос по синтаксису похож на S’L, и обычно используется для выполнения операций CRUD:

public UserEntity getUserByIdWithPlainQuery(Long id) {
    Query jpqlQuery = getEntityManager().createQuery("SELECT u FROM UserEntity u WHERE u.id=:id");
    jpqlQuery.setParameter("id", id);
    return (UserEntity) jpqlQuery.getSingleResult();
}

Этот Запрос извлекает соответствующий отчет из пользователи стол, а также карты его на ПользовательЕнтность объект.

Есть еще два Запрос подтипы:

  • Типированный Квери
  • По имени Квери

Давайте посмотрим на них в действии.

3.1. Тип-Квери

Мы должны обратить внимание на возвращение заявление в нашем предыдущем примере. JPA не может вывести то, что Запрос тип результата будет, и, как результат, мы должны бросить.

Но, JPA предоставляет специальную Запрос подтип, известный как Типированный Квери. Это всегда предпочтительнее, если мы знаем нашу Запрос тип результата заранее. Кроме того, это делает наш код гораздо более надежным и легким для тестирования.

Давайте посмотрим на Типированный Квери альтернатива, по сравнению с нашим первым примером:

public UserEntity getUserByIdWithTypedQuery(Long id) {
    TypedQuery typedQuery
      = getEntityManager().createQuery("SELECT u FROM UserEntity u WHERE u.id=:id", UserEntity.class);
    typedQuery.setParameter("id", id);
    return typedQuery.getSingleResult();
}

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

3.2. По имени Квери

Хотя мы можем динамически определить Запрос на конкретных методах, они могут в конечном итоге вырасти в трудно поддерживать кодовую базу. Что делать, если мы могли бы сохранить общие запросы использования в одном централизованном, легко читаемом месте?

JPA также получил нас охвачены по этому вопросу с другой Запрос подтип, известный как По имени Квери .

Мы определяем, По имени Квери на сущность сам класс, обеспечивая централизованный, быстрый и простой способ читать и находить сущность связанных с запросами.

Все По имени Квери должны иметь уникальное имя.

Давайте посмотрим, как мы можем добавить По имени Квери к нашему ПользовательЕнтность класс:

@Table(name = "users")
@Entity
@NamedQuery(name = "UserEntity.findByUserId", query = "SELECT u FROM UserEntity u WHERE u.id=:userId")
public class UserEntity {

    @Id
    private Long id;
    private String name;
    //Standard constructor, getters and setters.

}

тем @NamedQuery аннотация должна быть сгруппирована внутри @NamedQueries аннотация, если мы используем Java до версии 8. С Java 8 вперед, мы можем просто повторить @NamedQuery аннотация на нашем сущность класс.

Использование По имени Квери очень просто:

public UserEntity getUserByIdWithNamedQuery(Long id) {
    Query namedQuery = getEntityManager().createNamedQuery("UserEntity.findByUserId");
    namedQuery.setParameter("userId", id);
    return (UserEntity) namedQuery.getSingleResult();
}

4. Родные Квери

A Родной Квери это просто запрос S’L. Это позволяет нам раскрыть всю мощь нашей базы данных, так как мы можем использовать несвободные функции, недоступные в синтаксисе, ограниченном JP’L.

Это дорого обошлось. Мы теряем портативность базы данных нашего приложения с Родной Квери потому что наш поставщик JPA больше не может абстрагироваться от конкретных деталей от реализации базы данных или поставщика.

Давайте посмотрим, как использовать Родной Квери что дает те же результаты, что и наши предыдущие примеры:

public UserEntity getUserByIdWithNativeQuery(Long id) {
    Query nativeQuery
      = getEntityManager().createNativeQuery("SELECT * FROM users WHERE id=:userId", UserEntity.class);
    nativeQuery.setParameter("userId", id);
    return (UserEntity) nativeQuery.getSingleResult();
}

Мы всегда должны учитывать, если Родной Квери является единственным вариантом. Большую часть времени, хороший JP’L Запрос может выполнить наши потребности и, самое главное, поддерживать уровень абстракции от фактической реализации базы данных.

Использование Родной Квери не обязательно означает блокировку одного конкретного поставщика баз данных. В конце концов, если наши запросы не используют собственные команды S’L и используют только стандартный синтаксис S’L, переключение поставщиков не должно быть проблемой.

5. Критерий API запрос

Критерии запросов API программно-построенные, безопасные для типов запросы – несколько похожие на запросы JP’L в синтаксисе:

public UserEntity getUserByIdWithCriteriaQuery(Long id) {
    CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
    CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(UserEntity.class);
    Root userRoot = criteriaQuery.from(UserEntity.class);
    UserEntity queryResult = getEntityManager().createQuery(criteriaQuery.select(userRoot)
      .where(criteriaBuilder.equal(userRoot.get("id"), id)))
      .getSingleResult();
    return queryResult;
}

Это может быть сложной для использования Критерии API запрашивает запросы из первых рук, но они могут быть отличным выбором, когда нам нужно добавить динамические элементы запроса или в сочетании с JPA Метамодель.

6. Заключение

В этой быстрой статье мы узнали, что такое ЗАПРОСы JPA, наряду с их использованием.

Запросы JPA — это отличный способ абстрагировать нашу бизнес-логику от нашего уровня доступа к данным, так как мы можем полагаться на синтаксис JP-L и позволить нашему поставщику JPA по выбору обрабатывать Запрос перевод.

Весь код, представленный в данной статье, доступен более на GitHub .