Spring Data JPA分页排序结合报错,如何正确实现分页与排序?
解决Spring Data中分页与排序结合的问题
嘿,这个问题我之前也碰到过!咱们一步步来拆解原因和解决方案:
为什么会报错?
你写的findAllOrderByCreatedDate方法名不符合Spring Data JPA的方法命名规则。框架的方法名解析器会把OrderByCreatedDate误认为是查询条件的一部分(比如类似findByCreatedDate的格式),而不是排序规则,所以它会去寻找对应createdDate的查询参数,但你并没有传递,于是就抛出了找不到参数的错误。
正确的实现方式(两种推荐方案)
方案1:通过Pageable传递分页+排序(最灵活)
这种方式不需要自定义Repository方法,直接用Spring Data提供的默认findAll(Pageable pageable)方法即可,排序规则直接封装在Pageable对象里,后续要修改排序字段或方向也不用改Repository代码。
步骤如下:
- 确保你的Repository接口继承了
JpaRepository<MyDTO, Long>(或者PagingAndSortingRepository),它已经自带了findAll(Pageable pageable)的实现:
public interface MyDTORepository extends JpaRepository<MyDTO, Long> { }
- 在业务代码中构建包含排序的分页请求:
// 1. 定义排序规则:按createdDate字段降序排列(Asc是升序) Sort sort = Sort.by(Sort.Direction.DESC, "createdDate"); // 2. 构建分页请求:页码(注意Spring Data的页码从0开始!)、每页大小、排序规则 // 注意:PageRequest的构造器已过时,推荐用静态工厂方法PageRequest.of() Pageable pageable = PageRequest.of(pageNumber, pageSize, sort); // 3. 获取分页结果 Page<MyDTO> page = repo.findAll(pageable);
方案2:通过方法名指定排序(适合固定排序规则的场景)
如果你的排序规则是固定的(比如永远按createdDate降序),可以在Repository里定义一个带排序的方法,此时Pageable只用来传递分页参数:
- 在Repository中定义方法:
public interface MyDTORepository extends JpaRepository<MyDTO, Long> { // 按createdDate降序查询所有数据,分页参数由Pageable传入 Page<MyDTO> findAllByOrderByCreatedDateDesc(Pageable pageable); }
- 调用时只需要传递分页的页码和大小:
Pageable pageable = PageRequest.of(pageNumber, pageSize); Page<MyDTO> page = repo.findAllByOrderByCreatedDateDesc(pageable);
注意:方法名的格式必须是
findAllByOrderBy[PropertyName][Asc/Desc],By不能少,否则框架会解析错误。
额外注意事项
- 你的实体类用了
@Entity注解,但类名叫MyDTO,这有点不符合命名规范——DTO一般指数据传输对象,实体类建议命名为MyEntity之类的,不过这不会影响功能,只是代码可读性的问题。 - Spring Data Commons 2.0+版本中,
new PageRequest(...)的构造器已经被标记为过时,一定要用PageRequest.of()静态方法来创建分页请求对象。
内容的提问来源于stack exchange,提问作者jarosik




