Criteria API - пример выражений IN

1. Обзор

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

В этом руководстве мы узнаем, как решить эту проблему с помощью API критериев .

2. Примеры объектов

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

У нас есть класс DeptEmployee, который имеет отношение «многие к одному» с классом Department :

@Entity public class DeptEmployee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String title; @ManyToOne private Department department; }

Кроме того, объект Department, который сопоставляется с несколькими сотрудниками DeptEmployees :

@Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String name; @OneToMany(mappedBy="department") private List employees; }

3. CriteriaBuilder.In

Прежде всего, воспользуемся интерфейсом CriteriaBuilder . В () метод принимает выражение и возвращает новый Predicate из CriteriaBuilder.In типа . Его можно использовать для проверки, содержится ли данное выражение в списке значений:

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(DeptEmployee.class); Root root = criteriaQuery.from(DeptEmployee.class); In inClause = criteriaBuilder.in(root.get("title")); for (String title : titles) { inClause.value(title); } criteriaQuery.select(root).where(inClause);

4. Выражение.

В качестве альтернативы мы можем использовать набор перегруженных методов in () из интерфейса Expression :

criteriaQuery.select(root) .where(root.get("title") .in(titles));

В отличие от CriteriaBuilder. in () , Expression.in () принимает набор значений. Как мы видим, это также немного упрощает наш код.

5. Выражения IN с использованием подзапросов

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

Например, мы можем получить всех сотрудников DeptEmployee , принадлежащих к отделу, с указанным ключевым словом в их имени:

Subquery subquery = criteriaQuery.subquery(Department.class); Root dept = subquery.from(Department.class); subquery.select(dept) .distinct(true) .where(criteriaBuilder.like(dept.get("name"), "%" + searchKey + "%")); criteriaQuery.select(emp) .where(criteriaBuilder.in(emp.get("department")).value(subquery));

Здесь мы создали подзапрос, который затем был передан в value () в качестве выражения для поиска объекта Department .

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

В этой быстрой статье мы узнали о различных способах выполнения операции IN с помощью Criteria API. Мы также узнали, как использовать Criteria API с подзапросами.

Наконец, полная реализация этого руководства доступна на GitHub.