Criteria API - пример выражений IN
1. обзор
Мы часто сталкиваемся с проблемами, когда нам нужно запрашивать объекты на основе того, является ли однозначный атрибут членом данной коллекции.
В этом руководстве мы узнаем, как решить эту проблему с помощьюCriteria API.
2. Образцы сущностей
Прежде чем мы начнем, давайте взглянем на сущности, которые мы собираемся использовать в нашей статье.
У нас есть классDeptEmployee, у которого естьmany-to-one relationship с классом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. The in() method accepts an Expression and returns a new Predicate of the CriteriaBuilder.In type_._ Его можно использовать для проверки, содержится ли данное выражение в списке значений:
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. Expression.In
В качестве альтернативы мы можем использовать набор перегруженных методовin() из интерфейсаExpression:
criteriaQuery.select(root)
.where(root.get("title")
.in(titles));
In a contrast to the CriteriaBuilder.in(), the Expression.in() accepts a collection of values. Как мы видим, это также немного упрощает наш код.
5. В выражениях с использованием подзапросов
До сих пор мы использовали коллекции с предопределенными значениями. Теперь давайте рассмотрим пример, когда коллекция является производной от подзапроса.
Например, мы можем получить всехDeptEmployee, принадлежащих кDepartment,, с указанным ключевым словом в их имени:
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 с помощью API Criteria. Мы также изучили, как использовать Criteria API с подзапросами.
Наконец, полная реализация этого руководства -available on GitHub.