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

如何基于起始元素位置实现Spring Boot+JPA的自定义元素分页?

在Spring Boot + Hibernate中基于起始位置和数量实现JpaRepository分页(含自定义排序)

问题核心是你混淆了PageRequest.of(page, size)中page参数的含义——它代表从0开始的页码,底层会自动计算偏移量为page * size,这就是你得到第7-9条数据的原因(2*3=6,从第7条开始取3条)。

要实现基于起始位置(offset)和数量(limit)的分页,无需编写原生查询,利用Spring Data JPA提供的Pageable接口能力即可解决:

1. 构建正确的分页参数

使用PageRequest.ofSize(size).withOffset(offset)来创建包含起始位置、数量和排序规则的Pageable实例,其中:

  • offset:起始元素位置(从0开始计数,对应你需求中的起始位置2)
  • size:要返回的元素数量
  • 配合withSort()添加自定义排序规则

示例代码:

// 起始位置2,数量3,按指定字段降序排序
Pageable pageable = PageRequest.ofSize(3)
    .withOffset(2)
    .withSort(Sort.by("any sort").descending());

2. 调用JpaRepository的查询方法

JpaRepository自带的findAll(Pageable pageable)方法会根据传入的参数生成包含OFFSET和LIMIT的SQL,只会加载需要的目标数据,不会产生冗余:

public interface PersonRepository extends JpaRepository<Person, Long> {}

// 在业务逻辑中调用
List<Person> targetPersons = personRepository.findAll(pageable);

完整示例(Controller层)

修改接口参数,直接接收offset和排序相关参数,替代原有的页码参数:

@GetMapping("/persons")
List<Person> findEveryone(
    @RequestParam(required = false, defaultValue = "0") long offset,
    @RequestParam(required = false, defaultValue = "10") int size,
    @RequestParam(required = false, defaultValue = "id") String sortField,
    @RequestParam(required = false, defaultValue = "asc") String sortDir) {

    Sort sort = Sort.by(Sort.Direction.fromString(sortDir), sortField);
    Pageable pageable = PageRequest.ofSize(size).withOffset(offset).withSort(sort);
    return personRepository.findAll(pageable);
}

低版本兼容说明

如果你的Spring Boot版本低于2.2(对应Spring Data Commons低于2.2),可以通过自定义Pageable实现类来设置偏移量:

// 兼容低版本的写法
Sort sort = Sort.by("any sort").descending();
Pageable pageable = new PageRequest(0, size, sort) {
    @Override
    public long getOffset() {
        return offset; // 传入你的起始位置
    }
};

内容的提问来源于stack exchange,提问作者Rustem Zamaliev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:22:26