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

Запросы критериев JPA

Быстрое и практическое руководство по использованию механизма критериев запросов в Hibernate

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

Запросы критериев JPA

1. Обзор

В этом учебнике мы обсудим очень полезную функцию JPA – Критерии Запросы.

Это не только позволяет нам писать запросы, не делая необработанных S’L, но и дает нам некоторый объектно-ориентированный контроль над запросами, что является одной из основных особенностей Hibernate. API Criteria позволяет нам создавать критерии объекта запроса программно, где мы можем применять различные виды правил фильтрации и логических условий.

Начиная с Hibernate 5.2, API Критерии Hibernate является deprecated, и новая разработка ориентирована на API критериев JPA. Мы изучить, как использовать Hibernate и JPA для создания критериев запросов.

2. Мейвен зависимостей

Чтобы проиллюстрировать API, мы будем использовать справочную реализацию JPA – Hibernate.

Чтобы использовать Hibernate, убедитесь, что вы добавляете последнюю версию его в свой пом.xml файл:


    org.hibernate
    hibernate-core   
    5.3.2.Final

Мы можем найти последнюю версию Hibernate здесь.

3. Простой пример с использованием критериев

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

У нас есть Пункт класс, представляющий тупл “ITEM” в базе данных:

public class Item implements Serializable {

    private Integer itemId;
    private String itemName;
    private String itemDescription;
    private Integer itemPrice;

   // standard setters and getters
}

Рассмотрим простой запрос критериев, который будет получать все строки ” ПУНКТ” из базы данных:

Session session = HibernateUtil.getHibernateSession();
CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery cr = cb.createQuery(Item.class);
Root root = cr.from(Item.class);
cr.select(root);

Query query = session.createQuery(cr);
List results = query.getResultList();

Вышеупомянутый запрос является простой демонстрацией того, как получить все элементы. Давайте посмотрим, что было сделано, шаг за шагом:

  1. Создайте экземпляр Сессионая из СессияФактори объект
  2. Создание экземпляра C riteriaBuilder позвонив в getCriteriaBuilder() метод
  3. Создайте экземпляр Критерии Квери позвонив в КритерииСтроитель создать метод Квери ()
  4. Создайте экземпляр Запрос позвонив в Сессионая создать Квери () метод
  5. Позвони getResultList () метод запрос объект, который дает нам результаты

Теперь, когда мы рассмотрели основы, давайте перейдем к некоторым особенностям запроса критериев:

3.1. Использование выражений

КритерииСтроитель может использоваться для ограничения результатов запросов на основе конкретных условий. Используя Критерии Квери где () метод и обеспечить Выражения созданный КритерийСтроитель.

Вот несколько примеров часто используемых Выражения :

Чтобы получить товары по цене более 1000:

cr.select(root).where(cb.gt(root.get("itemPrice"), 1000));

Далее, получая элементы, имеющие пунктЦена менее 1000:

cr.select(root).where(cb.lt(root.get("itemPrice"), 1000));

Элементы, имеющие пунктИмя содержат Председатель :

cr.select(root).where(cb.like(root.get("itemName"), "%chair%"));

Записи, имеющие пунктЦена от 100 до 200:

cr.select(root).where(cb.between(root.get("itemPrice"), 100, 200));

Элементы, имеющие пунктИмя в Скейт-доску, и Клей :

cr.select(root).where(root.get("itemName").in("Skate Board", "Paint", "Glue"));

Чтобы проверить, является ли данное свойство недействительным:

cr.select(root).where(cb.isNull(root.get("itemDescription")));

Проверить, не является ли данное свойство недействительным:

cr.select(root).where(cb.isNotNull(root.get("itemDescription")));

Вы также можете использовать методы isEmpty () и isNotEmpty () проверить, если Список в классе пуста или нет.

Теперь неизбежно возникает вопрос, будь мы можем объединить два или более из вышеперечисленных сравнений или нет. Ответ, конечно, да – API Criteria позволяет нам легко цепные выражения :

Predicate[] predicates = new Predicate[2];
predicates[0] = cb.isNull(root.get("itemDescription"));
predicates[1] = cb.like(root.get("itemName"), "chair%");
cr.select(root).where(predicates);

Чтобы добавить два выражения с логическими операциями:

Predicate greaterThanPrice = cb.gt(root.get("itemPrice"), 1000);
Predicate chairItems = cb.like(root.get("itemName"), "Chair%");

Элементы с вышеуказанными условиями, соединенные с Логические или :

cr.select(root).where(cb.or(greaterThanPrice, chairItems));

Чтобы получить элементы, соответствующие вышеуказанным условиям, вместе с Логические и :

cr.select(root).where(cb.and(greaterThanPrice, chairItems));

3.2. Сортировка

Теперь, когда мы знаем основное использование Критерии , Давайте посмотрим на функциональность сортировки Критерии .

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

cr.orderBy(
  cb.asc(root.get("itemName")), 
  cb.desc(root.get("itemPrice")));

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

3.3. Прогнозы, агрегаты и функции группировки

До сих пор мы рассмотрели большинство основных тем. Теперь давайте посмотрим на различные агрегированные функции:

Получить количество строк:

CriteriaQuery cr = cb.createQuery(Long.class);
Root root = cr.from(Item.class);
cr.select(cb.count(root));
Query query = session.createQuery(cr);
List itemProjected = query.getResultList();

Ниже приводится пример агрегированных функций:

Совокупные функции для Средняя :

CriteriaQuery cr = cb.createQuery(Double.class);
Root root = cr.from(Item.class);
cr.select(cb.avg(root.get("itemPrice")));
Query query = session.createQuery(cr);
List avgItemPriceList = query.getResultList();

Другие полезные агрегированные методы, которые доступны, сумма () , макс () , мин() , рассчитывать () и так далее.

3.4. КритерииПодготовка

Начиная с JPA 2.1, существует поддержка для выполнения обновлений баз данных с использованием критерии API.

КритерииПодготовка имеет набор () метод, который может использоваться для предоставления новых значений для записей баз данных:

CriteriaUpdate criteriaUpdate = cb.createCriteriaUpdate(Item.class);
Root root = criteriaUpdate.from(Item.class);
criteriaUpdate.set("itemPrice", newPrice);
criteriaUpdate.where(cb.equal(root.get("itemPrice"), oldPrice));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaUpdate).executeUpdate();
transaction.commit();

В вышеупомянутом фрагменте мы создаем экземпляр КритерииПодготовка из КритерииСтроитель и использовать его набор () метод предоставления новых значений для itemPrice. Чтобы обновить несколько свойств, нам просто нужно позвонить в набор () метод несколько раз.

3.5. КритерииДелет

КритерииДелет, как следует из названия, позволяет удалить операцию с использованием Критерии API. Все, что нам нужно, это создать экземпляр КритерииДелет и использовать где () метод применения ограничений:

CriteriaDelete criteriaDelete = cb.createCriteriaDelete(Item.class);
Root root = criteriaDelete.from(Item.class);
criteriaDelete.where(cb.greaterThan(root.get("itemPrice"), targetPrice));

Transaction transaction = session.beginTransaction();
session.createQuery(criteriaDelete).executeUpdate();
transaction.commit();

4. Преимущество над H’L

В предыдущих разделах мы рассмотрели, как использовать критерии запросов.

Очевидно, Основным и наиболее неохвекым преимуществом критериев запросов по сравнению с H’L является хороший, чистый, объектно-ориентированный API.

Мы можем просто написать более гибкие, динамичные запросы по сравнению с простым h’L. Логика может быть рефакторинг с IDE и имеет все преимущества тип-безопасности самого языка Java.

Есть, конечно, некоторые недостатки, а также, особенно вокруг более сложных соединений.

Таким образом, в целом, мы должны использовать лучший инструмент для работы – это может быть API критериев в большинстве случаев, но Есть определенно случаи, когда нам придется пойти более низкого уровня.

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

В этой статье мы сосредоточились на основах критериев запросов в Hibernate и JPA, а также на некоторых расширенных функциях API.

Обсуждаемый здесь код доступен в Репозиторий Github .