Specifications
Динамический поиск из небольших условий
Представим экран поиска, где пользователь может независимо указать статус, имя, минимальный возраст и другие фильтры. Создавать отдельный метод репозитория для каждой комбинации быстро становится неудобно. В Spring Data JPA для таких случаев есть Specification — объект, описывающий одно условие запроса.
interface CustomerRepository
extends JpaRepository<Customer, Long>,
JpaSpecificationExecutor<Customer> {
}
Specification<Customer> active =
(root, query, cb) -> cb.isTrue(root.get("active"));
Specification<Customer> adult =
(root, query, cb) -> cb.greaterThanOrEqualTo(root.get("age"), 18);
List<Customer> customers = repository.findAll(active.and(adult));
Каждая спецификация описывает небольшой предикат.
Интерфейс JpaSpecificationExecutor добавляет методы, которые умеют выполнять такие условия,
а спецификации можно объединять через and, or и отрицание.
Когда Specifications особенно полезны
Они хорошо подходят для фильтров, набор которых определяется во время выполнения: например, часть полей поисковой формы может быть заполнена, а часть — нет. Код может добавить только нужные условия и затем передать готовую комбинацию репозиторию.
@Query обычно читается легче.