SpringJPA 做分页条件查询的代码实践

 更新时间:2024年03月28日 10:52:56   作者:大魔王的日常Log  
相信小伙伴们的项目很多都用到SpringJPA框架的吧,对于单表的增删改查利用jpa是很方便的,但是对于条件查询并且分页 是不是很多小伙伴不经常写到,今天给大家分享SpringJPA 做分页条件查询的案例代码,感兴趣的朋友一起看看吧

前言:

相信小伙伴们的项目很多都用到SpringJPA框架的吧,对于单表的增删改查利用jpa是很方便的,但是对于条件查询并且分页 是不是很多小伙伴不经常写到. 今天我整理了一下在这里分享一下.
话不多说直接上代码:

Controller:

@RestController
public class ProductInstanceController {
    @Autowired
    private ProductInstanceService productInstanceService;
    @PostMapping("page-find-instance")
    public PageInfoVO<ProductInst> pageFindInstance(@RequestBody ProductInstParams productInstParams) {
        return productInstanceService.pageFindInstance(productInstParams);
    }
}

Service:

@Service
public class ProductInstanceService {
    @Autowired
    private ProductInstRepository productInstRepository;
    public PageInfoVO<ProductInst> pageFindInstance(ProductInstParams productInstParams) {
        Sort.Direction direction = Sort.Direction.DESC;
        //创建一个Pageable对象,其中包含了请求的页码(productInstParams.getPageNo()),每页大小(productInstParams.getPageSize()),排序规则以及排序字段名。
        Pageable pageable = PageRequest.of(productInstParams.getPageNo(), productInstParams.getPageSize(), direction, "createdTime");
		//将传入的字符串类型的开始日期(startDate)和结束日期(endDate)转换成Date类型
        Date start = DateUtil.parseUTC(productInstParams.getStartDate());
        Date end = DateUtil.parseUTC(productInstParams.getEndDate());
        //执行JPA分页查询:
        Page<ProductInst> productInstPage = productInstRepository.findAll((root, query, criteriaBuilder) -> {
        //初始化一个ArrayList<Predicate>,存储多个谓词条件,这些条件最终会被组合成一个逻辑与(AND)表达式
            List<Predicate> predicatesAndList = new ArrayList<>();
            // deleted = 'true'
            if (null != productInstParams.getIsDeleted()) {
				predicatesAndList.add(criteriaBuilder.equal(root.get("deleted").as(Boolean.class), productInstParams.getIsDeleted()));
            }
            // name like %name%
            if (StringUtils.isNotBlank(productInstParams.getName())) {
                predicatesAndList.add(criteriaBuilder.like(root.get("name").as(String.class), productInstParams.getName()));
            }
            // runStatus = "运行中"
            if (StringUtils.isNotBlank(productInstParams.getRunStatus())) {
                predicatesAndList.add(criteriaBuilder.equal(root.get("runStatus").as(String.class), productInstParams.getRunStatus()));
            }
            // createdTime >= start
            if (!Objects.isNull(start)) {
                predicatesAndList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdTime").as(Date.class), start));
            }
            // createdTime <= end
            if (!Objects.isNull(end)) {
                predicatesAndList.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdTime").as(Date.class), end));
            }
            // id in ('1','2')
            if (!CollectionUtils.isEmpty(productInstParams.getIds())) {
                CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("id").as(String.class));
                productInstParams.getIds().forEach(in::value);
                predicatesAndList.add(in);
            }
            Predicate andPredicate = criteriaBuilder.and(predicatesAndList.toArray(new Predicate[predicatesAndList.size()]));
            query.where(andPredicate);
            return query.getRestriction();
        }, pageable);
        return PageUtil.generatePageInfoVO(productInstPage);
    }
}

解释:
jpa分页查询调的方法是:
Page findAll(@Nullable Specification spec, Pageable pageable);
该方法接受两个参数:
一个是 Specification 对象,用于构建复杂的查询条件;
另一个是之前创建的pageable对象,用于指定分页及排序信息。
点进去可以直接看到

下面我再解释一下这行代码

criteriaBuilder.equal(root.get("runStatus").as(String.class), productInstParams.getRunStatus());

1. criteriaBuilder 是javax.persistence.criteria.CriteriaBuilder的一个实例,它是用来构建JPQL查询条件的对象。

2. root 是代表查询主表的Root对象,它指向ProductInst实体类对应的数据库表。

3. root.get(“runStatus”) 表示获取ProductInst实体类中的runStatus属性(注意:这地方写的不是数据库的字段,我数据库的字段是:run_status)。这个方法返回的是一个Path<未知类型>对象,表示runStatus字段在查询路径上的位置。

4. .as(String.class) 是类型转换,确保runStatus被视为String类型,因为在数据库中它可能被映射为VARCHAR或者其他文本类型字段。

5. productInstParams.getRunStatus() 获取传入参数对象productInstParams中的runStatus属性值,这是一个待匹配的实际值。
综上所述:这段代码对应的sql

WHERE run_status = 'XXXX'

Repository:

@Repository
public interface ProductInstRepository extends JpaRepository<ProductInst, String>, JpaSpecificationExecutor<ProductInst> {
}

PageInfoVO:

package com.king.alice.common.base;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
 * @Author wlt
 * @Description 分页数据中的元素
 * @Date 2022/8/26
 **/
@Getter
@Setter
public class PageInfoVO<T> extends BaseVO{
    private static final long serialVersionUID = -3542944936096780651L;
    /**
     * 总记录数
     */
    private long total;
    /**
     * 当前页
     */
    private int pageNum;
    /**
     * 每页的数量
     */
    private int pageSize;
    /**
     * 结果集
     */
    private List<T> list;
}

PageUtil:

package com.king.alice.common.util;
import com.king.alice.common.base.PageInfoVO;
import org.springframework.data.domain.Page;
/**
 * @author 大魔王
 * @description:
 * @date 2024/3/22 11:02
 */
public class PageUtil {
    /**
     * 根据Page对象生成PageInfoVO
     *
     * @param page Page包装对象
     * @return PageDto 对象
     */
    @SuppressWarnings({"unchecked"})
    public static <T> PageInfoVO<T> generatePageInfoVO(Page page) {
        PageInfoVO result = new PageInfoVO();
        result.setPageNum(page.getNumber() + 1);
        result.setPageSize(page.getPageable().getPageSize());
        result.setTotal(page.getTotalElements());
        result.setList(page.getContent());
        return result;
    }
}

ProductInstParams:

package com.king.alice.manage.instance.params;
import lombok.Data;
import java.util.List;
/**
 * @author 大魔王
 * @description: TODO
 * @date 2024/3/21 16:56
 */
@Data
public class ProductInstParams {
    /**
     * 当前页
     */
    private int pageNo;
    /**
     * 每页的数量
     */
    private int pageSize;
    /**
     * 名字
     */
    private List<String> ids;
    /**
     * 名字
     */
    private String name;
    /**
     * 运行状态
     */
    private String runStatus;
    private String startDate;
    private String endDate;
    private Boolean isDeleted;
}

测试:

响应结果:

控制台打印sql:

到此这篇关于SpringJPA 做分页条件查询的文章就介绍到这了,更多相关SpringJPA 分页内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在MyBatis中使用接口映射的步骤详解

    在MyBatis中使用接口映射的步骤详解

    在MyBatis中使用接口映射是一种基于Java接口而非XML映射文件的方式来绑定SQL查询和操作,这种方法使用注解来指定SQL语句,并将其直接关联到接口方法上,本文给大家介绍了在MyBatis中使用接口映射的步骤,需要的朋友可以参考下
    2024-06-06
  • 浅析java中密文的创建和校验

    浅析java中密文的创建和校验

    这篇文章主要为大家详细介绍了java中密文的创建和校验的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-04-04
  • Java设计模式之浅谈外观模式

    Java设计模式之浅谈外观模式

    这篇文章主要介绍了Java设计模式之外观模式的相关资料,需要的朋友可以参考下
    2022-09-09
  • Java double转BigDecimal的注意事项说明

    Java double转BigDecimal的注意事项说明

    这篇文章主要介绍了Java double转BigDecimal的注意事项说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Java中String.join()高效字符串拼接的实现

    Java中String.join()高效字符串拼接的实现

    本文主要介绍了Java中String.join()高效字符串拼接的实现,包括基础拼接、StreamAPI结合、非字符串类型处理及与传统方式对比,具有一定的参考价值,感兴趣的可以了解一下
    2025-05-05
  • 深入解析四大主流Java AI Agent框架的选择与应用

    深入解析四大主流Java AI Agent框架的选择与应用

    本文将带你全面盘点当前主流的 Java AI Agent 框架,深入解析它们的技术特性、使用方式,并通过实战案例教你如何快速上手,快跟随小编一起学习起来吧
    2026-04-04
  • spring MVC搭建及配置详解

    spring MVC搭建及配置详解

    本篇文章主要介绍了spring MVC配置方法,要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理,有兴趣的可以了解一下。
    2017-01-01
  • Spring Boot Web应用开发 CORS 跨域请求支持

    Spring Boot Web应用开发 CORS 跨域请求支持

    本篇文章主要介绍了Spring Boot Web应用开发 CORS 跨域请求支持,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • Springboot敏感字段脱敏的实现思路

    Springboot敏感字段脱敏的实现思路

    这篇文章主要介绍了Springboot敏感字段脱敏的实现思路,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • 解决Error occurred during initialization of VM Java虚拟机初始化失败问题

    解决Error occurred during initialization o

    这篇文章主要介绍了解决Error occurred during initialization of VM Java虚拟机初始化失败问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03

最新评论