Java criteria predicate and

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

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

1. Обзор

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

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

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

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

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

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

Мы можем легко сделать это с помощью 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. Объединение двух предикатов И С использованием Предиката ИЛИ

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

Логика довольно схожа, но здесь мы сначала создаем два И Предиката 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 .

Читайте ещё по теме:

Источник

JPA — запрос с критерием. Использование API-интерфейса критериев JPA 2

Настройки взяты из JPA – пример приложения Hello World, используемые здесь сущности взяты в измененной версии JPA – операции INSERT, UPDATE, DELETE.

2. Создание метамодели с использованием JPA-интерфейса критериев

Описание и генерацию метамодели для нашего примера вынес в отдельную статью — Создание метамодели для сущностного класса в JPA 2. Приведу полученный результат:

Как видите в сгенерированной метамодели используется аннотация @StaticMetamodel(ContactEntity.class) с указанием сущностного класса. Обратите внимание, что класс метамодели ContactEntity_.class лежит в том же пакете, что и сущность ContactEntity.class .

После создания метамодели появляется возможность создания запроса с критерием, который будет проверяться на этапе компиляции, а не во время выполнения, т.к. он строго типизирован.

3. Создание запроса с критерием

Создадим один метод для запроса с критерием JPA 2:

javax . persistence . criteria . CriteriaQuery criteriaQuery = cb . createQuery ( ContactEntity . class ) ;

  • Создаем экземпляр CriteriaBuilder с помощью вызова EntityManager.getCriteriaBuilder()
  • Создаем типизированный запрос с помощью билдера, передавая параметром результирующий тип. Используется CriteriaQuery из пакета javax.persistence .
  • Формируем основу для путевых выражений внутри запроса. Для этого вызывается CriteriaQuery.from() с передачей сущностного класса в качестве параметра. Результатом станет объект корня запроса Root .
  • Root.fetch() обеспечивает незамедлительную выборку (по умолчанию в Hibernate (поставщик постоянства для JPA) — отложенная выборка). JoinType.LEFT — задает внешнее соединение. *Если вы читали предыдущие статьи, то выражение эквивалентно left join fetch в JPQL.
  • Далее вызов CriteriaQuery.select() вместе с параметром корня запроса и методом distinct(true) . Последний метод устранит дублированные записи.
  • Экземпляр Predicate — ограничение, которое указывает критерий выборки, определенный выражением. Может быть простым или сложным. Получаем с помощью вызова CriteriaBuilder.conjuction() .
  • equal() — ожидаемо означает равенство. Внутри него вызывается Root.get() в котором передается атрибут метамодели сущностного класса, к которому будет применяться ограничение. CriteriaBuilder.and() объединяет предикат с существующим предикатом из переменной criteria .
  • Полученный предикат со всеми ограничениями передается запросу с помощью CriteriaQuery.where() .
  • Создаем и вызываем запрос.

4. Тестирование запроса с критерием

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

Источник

JPA Criteria API — Applying in() Predicate

Following example shows how to use Expression.in() methods.

These methods test whether the expression is a member of the provided argument list.

package javax.persistence.criteria; . public interface Expression extends Selection < . Predicate in(Object. values); Predicate in(Expression. values); Predicate in(Collection values); Predicate in(Expression values); . >

Example

Entity

@Entity public class Employee

Using in() methods

public class ExampleMain < private static EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("example-unit"); public static void main(String[] args) < try < persistEmployees(); findEmployeeBySalary(); findEmployeeByName(); findEmployeeByDept(); >finally < entityManagerFactory.close(); >> private static void findEmployeeBySalary() < System.out.println("-- Employees with salary IN 2000, 3000 and 4000 --"); EntityManager em = entityManagerFactory.createEntityManager(); CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQueryquery = criteriaBuilder.createQuery(Employee.class); Root employee = query.from(Employee.class); query.select(employee) .where(employee.get(Employee_.salary).in(2000, 3000, 4000)); TypedQuery typedQuery = em.createQuery(query); List resultList = typedQuery.getResultList(); resultList.forEach(System.out::println); em.close(); > //negating IN predicate private static void findEmployeeByName() < System.out.println("-- Employees name NOT IN Diana and Rose --"); EntityManager em = entityManagerFactory.createEntityManager(); CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQueryquery = criteriaBuilder.createQuery(Employee.class); Root employee = query.from(Employee.class); query.select(employee) .where(employee.get(Employee_.name).in("Diana", "Rose").not()); TypedQuery typedQuery = em.createQuery(query); List resultList = typedQuery.getResultList(); resultList.forEach(System.out::println); em.close(); > //using Predicate in(Expression. values); private static void findEmployeeByDept() < System.out.println("-- Employees dept IN IT, Sales and HR --"); EntityManager em = entityManagerFactory.createEntityManager(); CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQueryquery = criteriaBuilder.createQuery(Employee.class); Root employee = query.from(Employee.class); ParameterExpression deptParamExpression = criteriaBuilder.parameter(Collection.class); query.select(employee) .where(employee.get(Employee_.dept).in(deptParamExpression)); TypedQuery typedQuery = em.createQuery(query); typedQuery.setParameter(deptParamExpression, Arrays.asList("IT", "Sales", "HR")); List resultList = typedQuery.getResultList(); resultList.forEach(System.out::println); em.close(); > public static void persistEmployees() < Employee employee1 = Employee.create("Diana", "IT", 3000); Employee employee2 = Employee.create("Rose", "Sales", 2000); Employee employee3 = Employee.create("Denise", "Admin", 4000); Employee employee4 = Employee.create("Mike", "HR", 3500); EntityManager em = entityManagerFactory.createEntityManager(); em.getTransaction().begin(); em.persist(employee1); em.persist(employee2); em.persist(employee3); em.persist(employee4); em.getTransaction().commit(); em.close(); System.out.println("-- employees persisted --"); System.out.println(employee1); System.out.println(employee2); System.out.println(employee3); System.out.println(employee4); >>
-- employees persisted --
Employee
Employee
Employee
Employee
-- Employees with salary IN 2000, 3000 and 4000 --
Employee
Employee
Employee
-- Employees name NOT IN Diana and Rose --
Employee
Employee
-- Employees dept IN IT, Sales and HR --
Employee
Employee
Employee

Example Project

Dependencies and Technologies Used:

  • h2 1.4.197: H2 Database Engine.
  • hibernate-core 5.3.6.Final: Hibernate’s core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • hibernate-jpamodelgen 5.3.6.Final: Annotation Processor to generate JPA 2 static metamodel classes.
  • JDK 1.8
  • Maven 3.5.4

Источник

Читайте также:  Pip install graph python
Оцените статью