Spring Boot 2.7.8中为何需要countQuery?有无其他分页实现方式?
Spring Boot 2.7.8 分页实现优化方案
针对你的问题,分两种场景给出解决方案:
1. 非原生SQL(JPQL)场景
如果你的查询可以用JPQL编写,直接返回Page类型即可,Spring Data JPA会自动生成对应的count查询,不需要额外的count方法或countQuery参数:
@Query("select pm from ProductMaster pm where pm.status != 2") Page<ProductMaster> findActiveProducts(Pageable pageable);
框架会自动解析JPQL语句,生成数据查询和总条数查询两个SQL,无需手动维护重复代码。
2. 原生SQL(nativeQuery=true)场景
在Spring Boot 2.7.8版本中,由于原生SQL语法灵活多样,框架无法可靠地自动将数据查询转换为count查询,因此必须显式指定count逻辑,但可以优化写法避免重复代码:
优化方案:提取查询常量
把数据查询和count查询的SQL提取为常量,避免代码冗余:
private static final String PRODUCT_DATA_QUERY = "select * FROM product_master pm WHERE pm.product_id NOT IN (SELECT product_id FROM product_soc_details soc where soc.product_soc_id= :copysocid or soc.product_soc_id= :socid) and pm.status!=2 "; private static final String PRODUCT_COUNT_QUERY = "select count(*) FROM product_master pm WHERE pm.product_id NOT IN (SELECT product_id FROM product_soc_details soc where soc.product_soc_id= :copysocid or soc.product_soc_id= :socid) and pm.status!=2 "; @Query(value = PRODUCT_DATA_QUERY, countQuery = PRODUCT_COUNT_QUERY, nativeQuery = true) Page<ProductMaster> findProductsByFilterinProductSocAllCopy(int copysocid, int socid, Pageable pageable);
替代方案:使用Specification
如果你的查询条件是动态的,可以实现JpaSpecificationExecutor接口,通过Specification构建查询条件,框架会自动处理分页的数据查询和count查询:
// 仓库接口继承JpaSpecificationExecutor public interface ProductMasterRepository extends JpaRepository<ProductMaster, Long>, JpaSpecificationExecutor<ProductMaster> { } // 业务层构建Specification并分页查询 Specification<ProductMaster> spec = (root, query, cb) -> { // 构建查询条件,对应你的原生SQL逻辑 Subquery<Long> subquery = query.subquery(Long.class); Root<ProductSocDetails> socRoot = subquery.from(ProductSocDetails.class); subquery.select(socRoot.get("productId")) .where(cb.or( cb.equal(socRoot.get("productSocId"), copysocid), cb.equal(socRoot.get("productSocId"), socid) )); return cb.and( cb.not(root.get("productId").in(subquery)), cb.notEqual(root.get("status"), 2) ); }; Page<ProductMaster> page = productMasterRepository.findAll(spec, pageable);
这种方式完全不需要手动编写count查询,由框架自动生成,适合复杂动态查询场景。
总结:JPQL场景下可以直接返回Page实现无额外代码的分页;原生SQL场景下2.7.8版本无法省略countQuery,但可以通过提取常量或使用Specification优化实现。
内容的提问来源于stack exchange,提问作者demo account
相关产品推荐
相关产品推荐

