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

Объединение Предикатов JPA И/Или Критериев

Узнайте, как использовать API критериев JPA для реализации случаев использования, когда нам нужно было объединить И/ИЛИ предикаты.

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

1. Обзор

API критериев JPA можно использовать для простого добавления нескольких И/ИЛИ условий при запросе записей в базе данных. В этом руководстве мы рассмотрим краткий пример запросов критериев JPA, которые объединяют несколько предикатов И/ИЛИ предикатов.

Если вы не знакомы с предикатами, мы рекомендуем сначала прочитать об основных запросах критериев JPA.

2. Пример приложения

Для наших примеров мы рассмотрим инвентаризацию Элемент сущности, каждая из которых имеет идентификатор, | имя , цвет и класс :

@Entity
public class Item {

    @Id
    private Long id;
    private String color;
    private String grade;
    private String name;
    
    // standard getters and setters
}

3. Объединение Двух Предикатов ИЛИ С Использованием Предиката И

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

  1. красный или синий цвет
    И
  2. Класс А или В

Мы можем легко сделать это с помощью API критериев JPA и() и или() составных предикатов .

Для начала давайте настроим ваш запрос:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Item.class);
Root itemRoot = criteriaQuery.from(Item.class);

Теперь нам нужно будет построить Предикат , чтобы найти элементы, имеющие синий или красный цвет:

Predicate predicateForBlueColor
  = criteriaBuilder.equal(itemRoot.get("color"), "blue");
Predicate predicateForRedColor
  = criteriaBuilder.equal(itemRoot.get("color"), "red");
Predicate predicateForColor
  = criteriaBuilder.or(predicateForBlueColor, predicateForRedColor);

Далее, давайте построим Предикат , чтобы найти элементы класса A или B:

Predicate predicateForGradeA
  = criteriaBuilder.equal(itemRoot.get("grade"), "A");
Predicate predicateForGradeB
  = criteriaBuilder.equal(itemRoot.get("grade"), "B");
Predicate predicateForGrade
  = criteriaBuilder.or(predicateForGradeA, predicateForGradeB);

Наконец, мы определяем И Предикат из этих двух, применяем метод where() и выполняем наш запрос:

Predicate finalPredicate
  = criteriaBuilder.and(predicateForColor, predicateForGrade);
criteriaQuery.where(finalPredicate);
List items = entityManager.createQuery(criteriaQuery).getResultList();

4. Объединение двух предикатов И С использованием Предиката ИЛИ

С другой стороны, давайте рассмотрим случай, когда нам нужно найти предметы, имеющие либо:

  1. красный цвет и класс D ИЛИ
  2. синий цвет и класс В

Логика довольно схожа, но здесь мы сначала создаем два И Предиката s, а затем объединяем их с помощью ИЛИ Предиката :

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Item.class);
Root itemRoot = criteriaQuery.from(Item.class);

Predicate predicateForBlueColor
  = criteriaBuilder.equal(itemRoot.get("color"), "red");
Predicate predicateForGradeA
  = criteriaBuilder.equal(itemRoot.get("grade"), "D");
Predicate predicateForBlueColorAndGradeA
  = criteriaBuilder.and(predicateForBlueColor, predicateForGradeA);

Predicate predicateForRedColor
  = criteriaBuilder.equal(itemRoot.get("color"), "blue");
Predicate predicateForGradeB
  = criteriaBuilder.equal(itemRoot.get("grade"), "B");
Predicate predicateForRedColorAndGradeB
  = criteriaBuilder.and(predicateForRedColor, predicateForGradeB);

Predicate finalPredicate
  = criteriaBuilder
  .or(predicateForBlueColorAndGradeA, predicateForRedColorAndGradeB);
criteriaQuery.where(finalPredicate);
List items = entityManager.createQuery(criteriaQuery).getResultList();

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

В этом уроке мы использовали API критериев JPA для реализации случаев использования, когда нам нужно было объединить И/ИЛИ предикаты.

Как обычно, полный исходный код, используемый для этого урока, находится на GitHub .