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:

org.springframework.data.jpa.repository.JpaSpecificationExecutor
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:数量大小

 

注:以上蓝色字段为传参

posted @   earth唯一的你  阅读(232)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示