Spring Data JPA で遊んでみる 〜その9〜
昨日のSpecificationの続きでSpecificationを複数組み合わせて使う際に便利な、Specificationsというヘルパークラスが用意されている。
public class Specifications<T> implements Specification<T> { private final Specification<T> spec; private Specifications(Specification<T> spec) {...} public static <T> Specifications<T> where(Specification<T> spec) {...} public Specifications<T> and(final Specification<T> other) {...} public Specifications<T> or(final Specification<T> other) {...} public static <T> Specifications<T> not(final Specification<T> spec) {...} public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {...} }
幾つかメソッドが定義されていますがwhereを基点としてandとかorとかでつなげていく感じ。
例えば2つSpecがあるとして
public class EmpSpecifications { public static Specification<Emp> idLessThanOrEqualTo(final Long id) { return new Specification<Emp>() { @Override public Predicate toPredicate(Root<Emp> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.lessThanOrEqualTo(root.get(Emp_.id), id); } }; } public static Specification<Emp> hasDept(final Dept dept) { return new Specification<Emp>() { @Override public Predicate toPredicate(Root<Emp> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.equal(root.get(Emp_.dept), dept); } }; } }
これを組み合わせて使う場合は
List<Emp> emps = repository.findAll(where(idLessThanOrEqualTo(9L)).and(hasDept(Dept.of(1L))));
とかいうふうに使えます。
サンプルこのへん。
https://github.com/yamkazu/springdata-jpa-example/tree/complexspec