🚤
【Java】Spring Data JPAのFetchableFluentQueryをSpecificationに適用してみた
概要
Spring Data JPAのFetchableFluentQueryとは、インターフェース FluentQuery.FetchableFluentQuery<T>のドキュメントにある通り、元となるクエリに対して操作を加えることができるインターフェースです。具体的には取得する件数を制限したり、結果に含めるプロパティを指定したりするなどです。
今回はSpecificationで条件を作成したクエリで、FetchableFluentQueryを使用してみたのでそのメモ書きです。
前提
- 使用したSpring Data JPAのバージョンは
3.5.0です。
実装サンプル
まずは以下のようなSpecificationを用意します。
static Specification<TaskDefinitionEntity> specificationHasOwnerUserId(String ownerUserId, Optional<String> definitionIdOptional) {
return (root, query, criteriaBuilder) -> {
// LEFT JOINでcategoryを取得
Join<TaskDefinitionEntity, TaskCategoryEntity> categoryJoin =
root.join("category", JoinType.LEFT);
// 条件のリストを作成
var predicates = new ArrayList<Predicate>();
// 基本条件(ownerUserId)
predicates.add(criteriaBuilder.equal(root.get("ownerUserId"), ownerUserId));
// 条件付きでdefinitionIdの条件を追加
if (definitionIdOptional.isPresent()) {
predicates.add(criteriaBuilder.equal(root.get("id"), definitionIdOptional.get()));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
このSpecificationを使用する時に、FetchableFluentQueryを適用してみます。以下のように結合したテーブルのデータを取得するためプロパティ名を指定するのと、limitを設定してみます。
var specifications = TaskDefinitionRepository.specificationHasOwnerUserId(userId, Optional.empty());
// 結合したテーブルのプロパティ名を指定しデータ取得&limitを設定
var queryResult = taskDefinitionRepository.findBy(specifications, fetchable ->
fetchable.project("category").limit(300).all());
Discussion