1. 概述

当我们面对大量数据时,分页展示是一种非常常见的需求。同时,用户往往还希望这些数据能按照某个字段进行排序。

本篇文章将带你快速掌握如何在 Spring Data JPA 中实现分页与排序功能。

2. 初始设置

假设我们有一个 Product 实体类,用于表示商品信息:

@Entity 
public class Product {
    
    @Id
    private long id;
    private String name;
    private double price; 

    // 构造函数、getter 和 setter 省略
}

每个 Product 实例包含一个唯一标识 id、商品名称 name 和价格 price

3. 创建 Repository

为了访问 Product 数据,我们需要定义一个继承自 PagingAndSortingRepository 的接口:

public interface ProductRepository extends PagingAndSortingRepository<Product, Long> {

    List<Product> findAllByPrice(double price, Pageable pageable);
}

继承 PagingAndSortingRepository 后,我们可以直接使用以下两个方法:

  • findAll(Pageable pageable):用于分页查询
  • findAll(Sort sort):用于排序查询

⚠️ 注意:也可以选择继承 JpaRepository,它也包含了 PagingAndSortingRepository 的所有功能。

✅ 此外,我们还可以自定义方法,并通过 PageableSort 参数实现分页和排序逻辑,例如上面的 findAllByPrice 方法。

4. 分页查询

要实现分页,只需两步:

  1. 创建 PageRequest 对象(它是 Pageable 接口的一个实现)
  2. 将该对象作为参数传递给 Repository 方法

示例代码

// 第一页,每页显示 2 条数据
Pageable firstPageWithTwoElements = PageRequest.of(0, 2);

// 第二页,每页显示 5 条数据
Pageable secondPageWithFiveElements = PageRequest.of(1, 5);

⚠️ 页码从 0 开始计数。

在 Spring MVC 中,还可以借助 Spring Data Web Support 自动绑定 Pageable 参数。

调用 Repository 方法示例:

Page<Product> allProducts = productRepository.findAll(firstPageWithTwoElements);

List<Product> allTenDollarProducts = 
  productRepository.findAllByPrice(10, secondPageWithFiveElements);

返回值类型说明

  • Page<T>:除了返回数据列表,还会执行一次 count 查询来获取总页数 ❌ 有性能开销
  • Slice<T>:只判断是否有下一页 ✅ 更轻量
  • List<T>:仅返回数据列表,不关心总数 ✅ 最轻量

5. 排序 + 分页组合使用

如果只想排序,可以直接传入 Sort 对象:

Page<Product> allProductsSortedByName = productRepository.findAll(Sort.by("name"));

但如果既要分页又要排序,可以将 Sort 信息封装进 PageRequest

// 按 name 升序,第一页,每页 3 条
Pageable sortedByName = PageRequest.of(0, 3, Sort.by("name"));

// 按 price 降序,第一页,每页 3 条
Pageable sortedByPriceDesc = PageRequest.of(0, 3, Sort.by("price").descending());

// 多字段排序:price 降序,name 升序,第一页,每页 5 条
Pageable sortedByPriceDescNameAsc = 
  PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));

创建好 Pageable 后,传入 Repository 方法即可:

productRepository.findAll(sortedByName);

6. 总结

这篇文章介绍了如何使用 Spring Data JPA 进行分页和排序操作:

  • 使用 PagingAndSortingRepository 提供的默认方法或自定义方法
  • 利用 PageRequest 构建分页请求
  • 通过 Sort 实现排序逻辑
  • 根据性能需求选择合适的返回类型:Page / Slice / List

✅ 完整代码示例可参考 GitHub 项目地址


原始标题:Pagination and Sorting using Spring Data JPA

« 上一篇: RSocket 简介