Spring Data JPA で遊んでみる 〜その8〜

Specificationの話です。

SpecificationはDDDのパターンの一つですが、JPA2から導入されたCriteriaを利用して、Spring Data JPAではSpecificationパターンみたいなことが出来ます。

Specificationを使用するにはリポジトリの定義でJpaSpecificationExecutorを継承する必要があります。

public interface EmpRepository extends JpaRepository<Emp, Long>, JpaSpecificationExecutor<Emp> {
//..

JpaSpecificationExecutorに定義されているメソッドは以下のようなもの。

T findOne(Specification<T> spec);
List<T> findAll(Specification<T> spec);
Page<T> findAll(Specification<T> spec, Pageable pageable);
List<T> findAll(Specification<T> spec, Sort sort);
long count(Specification<T> spec);

要はSpecificationを生成して引数として渡します。中身はCriteriaで条件を指定していきます。
こんなん

    public class Specifications {
        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);
                }
            };
        }
    }

使うときは

    @Test
    public void Specificationを使ってみる() throws Exception {
        List<Emp> emps = repository.findAll(idLessThanOrEqualTo(4L));
        assertThat(emps.size(), is(not(equalTo(0))));
    }

こんな感じになるわけです。

なかなかよいかも。

サンプルはこのへん。
https://github.com/yamkazu/springdata-jpa-example/tree/specification