spring data jpa specification实现复杂查询
持久化API概述:
1、JPA持久化API主要如下:
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID>
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>
public interface JpaRepositoryImplementation<T, ID> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID>
2、JpaRepository 接口拥有常用的 CURD 方法以及分页方法、字段排序等操作,
但是没有与或非、like、以及大于等于、小于等于等操作,
这些方法都在 JpaSpecificationExecutor 接口中。
3、如果只需要简单的实现 CRUD、分页、排序,则继承 JpaRepository接口即可,
如果还需要复杂查询,则可以再继承 JpaSpecificationExecutor 接口,也可以直接继承 JpaRepositoryImplementation 接口
JpaSpecificationExecutor 中 API:
| List<T>findAll(@Nullable Specification<T> spec) | 规范查询,没有数据时返回空列表。 |
| Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable) | 规范查询,同时进行分页查询。 |
| List<T> findAll(@Nullable Specification<T> spec, Sort sort) | 规范查询,同时指定排序字段。 |
| Optional<T> findOne(@Nullable Specification<T> spec) | 规范查询单条数据,注意如果结果多余一条,则抛异常。 |
| long count(@Nullable Specification<T> spec) | 规范查询,返回查询到的记录数 |
JPA Specification构建 (匿名内部类实现)
1.条件查询
Specification specification = new Specification<TV>() {
@Override
public Predicate toPredicate(Root<TV> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicateList = new ArrayList<>();
//条件1:查询 tvName 为 海信 的数据,root.get 中的值与 TV 实体中的属性名称对应
predicateList.add(cb.equal(root.get("tvName").as(String.class), tvName));
//条件2:TV 生产日期(dateOfProduction)大于等于 start 的数据
predicateList.add(cb.greaterThanOrEqualTo(root.get("dateOfProduction").as(Date.class), start));
//条件3:TV 生产日期(dateOfProduction)小于等于 end 的数据
predicateList.add(cb.lessThanOrEqualTo(root.get("dateOfProduction").as(Date.class), end));
Predicate[] pre = new Predicate[predicateList.size()];
pre = predicateList.toArray(pre);
return query.where(pre).getRestriction();
}
};
2.模糊查询
Specification<TV> tvSpecification = new Specification<TV>() {
@Override
public Predicate toPredicate(Root<TV> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate[] predicates = new Predicate[1];
predicates[0] = cb.like(root.get("tvName").as(String.class), "%" + tvNameLike + "%");
return query.where(predicates).getRestriction();
}
};
3.查询并排序
tvRepository.findAll(tvSpecification, Sort.by(Sort.Direction.DESC, "tvId"))
4.分页查询
//可以使用重载的 of(int page, int size, Sort sort) 方法指定排序字段
Pageable pageable = PageRequest.of(page, size)
page:第几页
size:数量大小
注:以上蓝色字段为传参

浙公网安备 33010602011771号