You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Data JPA分页排序结合报错,如何正确实现分页与排序?

解决Spring Data中分页与排序结合的问题

嘿,这个问题我之前也碰到过!咱们一步步来拆解原因和解决方案:

为什么会报错?

你写的findAllOrderByCreatedDate方法名不符合Spring Data JPA的方法命名规则。框架的方法名解析器会把OrderByCreatedDate误认为是查询条件的一部分(比如类似findByCreatedDate的格式),而不是排序规则,所以它会去寻找对应createdDate的查询参数,但你并没有传递,于是就抛出了找不到参数的错误。

正确的实现方式(两种推荐方案)

方案1:通过Pageable传递分页+排序(最灵活)

这种方式不需要自定义Repository方法,直接用Spring Data提供的默认findAll(Pageable pageable)方法即可,排序规则直接封装在Pageable对象里,后续要修改排序字段或方向也不用改Repository代码。

步骤如下:

  1. 确保你的Repository接口继承了JpaRepository<MyDTO, Long>(或者PagingAndSortingRepository),它已经自带了findAll(Pageable pageable)的实现:
public interface MyDTORepository extends JpaRepository<MyDTO, Long> {
}
  1. 在业务代码中构建包含排序的分页请求:
// 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只用来传递分页参数:

  1. 在Repository中定义方法:
public interface MyDTORepository extends JpaRepository<MyDTO, Long> {
    // 按createdDate降序查询所有数据,分页参数由Pageable传入
    Page<MyDTO> findAllByOrderByCreatedDateDesc(Pageable pageable);
}
  1. 调用时只需要传递分页的页码和大小:
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

火山引擎 最新活动