You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为自定义JPA原生查询添加正确的分页功能?

自定义JPA原生查询分页的正确实现方案

问题根因

你的代码存在3个核心错误导致查询返回空:

  • PageRequest的页码默认从0开始计数,你前端传入的页码是1,对应查询的是偏移量为10的第二页数据,如果总数据不足10条自然返回空
  • 原生SQL查询返回Page类型时,必须显式指定countQuery统计总条数,否则JPA无法正确计算分页参数
  • Service层代码笔误用了agentRepository,而非你定义的HeroRepository,同时SUM字段未指定别名无法和IHero接口映射

修复步骤

1. 修正Repository层代码

给@Query注解补充countQuery属性,给求和字段指定和IHero匹配的别名,调整分页占位符写法提升兼容性:

public interface HeroRepository extends JpaRepository<Hero,Long>{
    @Query(
        value = "SELECT h.heroname , SUM(h.killCount) AS killcount FROM Heroes AS h GROUP BY h.heroname ORDER BY h.heroname ?#{#pageable}",
        countQuery = "SELECT COUNT(*) FROM (SELECT h.heroname FROM Heroes AS h GROUP BY h.heroname) temp",
        nativeQuery = true
    )     
    Page<IHero> findAllHeroByGroupName(Pageable pageable);
}

2. 修正Service层代码

  • 修正Repository注入的变量名
  • 把传入的页码减1,适配PageRequest0起始的规则
public Page<IHero> findAllHeroByGroupName(int pageNum) {    
    // 页码减1处理,适配Spring Data 0起始的页码规则
    Pageable pageable = PageRequest.of(pageNum - 1, 10);    
    return heroRepository.findAllHeroByGroupName(pageable);   
}

3. 可选优化:修正Controller日志代码

你当前打印的是全局变量heroList的长度,而非查询返回的分页数据长度,建议修改日志方便排查:

@GetMapping("/heropage/{pageNum}")
public String viewHeroPage(Model model, 
        @PathVariable(name = "pageNum") int pageNum) {
    
     Page<IHero> page = heroService.findAllHeroByGroupName(pageNum);
     // 打印实际查询到的分页数据长度
     System.out.println("查询到的英雄列表长度:" + page.getContent().size());
    
     model.addAttribute("currentPage", pageNum);        
     model.addAttribute("totalPages", page.getTotalPages());
     model.addAttribute("totalItems", page.getTotalElements());

     model.addAttribute("heroList", page.getContent() );
     return "heropage";
}

修改后即可正常返回分页数据,原有非分页查询的逻辑不受影响。

内容的提问来源于stack exchange,提问作者Joona Ritva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:15:04