在 Spring Boot 中实现分页和排序通常是通过 Spring Data JPA 或者 Spring Data MongoDB 提供的分页功能来完成的。以下是一个基于 Spring Data JPA 的分页和排序实现的基本步骤。

1. 添加依赖

首先,确保你在 pom.xml 中包含了 Spring Data JPA 和数据库驱动的依赖。

<dependencies>
    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    <!-- 你使用的数据库驱动,例如 H2 或 MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    
    <!-- Spring Boot Starter Web(用于构建RESTful API) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

2. 创建实体类

例如,创建一个 Product 实体类。

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Product {
    
    @Id
    private Long id;
    private String name;
    private Double price;

    // Getters and Setters
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

3. 创建 Repository 接口

使用 Spring Data JPA 提供的 PagingAndSortingRepository 接口,或者继承 JpaRepository 接口,这样可以直接使用分页和排序功能。

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ProductRepository extends JpaRepository<Product, Long> {
    // 可以根据需要添加自定义查询
    Page<Product> findByNameContaining(String name, Pageable pageable);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

4. 创建 Service 层

在服务层中编写分页和排序的逻辑。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

@Service
public class ProductService {
    
    @Autowired
    private ProductRepository productRepository;
    
    // 获取分页和排序的产品列表
    public Page<Product> getProducts(int page, int size, String sortBy, String direction) {
        Sort sort = direction.equalsIgnoreCase("asc") ? Sort.by(sortBy).ascending() : Sort.by(sortBy).descending();
        Pageable pageable = PageRequest.of(page, size, sort);
        return productRepository.findAll(pageable);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

5. 创建 Controller 层

在 Controller 中创建一个接口,接受分页和排序的参数,并返回分页后的数据。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProductController {
    
    @Autowired
    private ProductService productService;
    
    // 获取分页和排序的产品列表
    @GetMapping("/products")
    public Page<Product> getProducts(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "name") String sortBy,
            @RequestParam(defaultValue = "asc") String direction) {
        
        return productService.getProducts(page, size, sortBy, direction);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

6. 测试接口

启动应用程序后,访问分页和排序的接口。比如:

  • 获取第一页(10条)按 name 升序排序的产品:
GET /products?page=0&size=10&sortBy=name&direction=asc
  • 1.
  • 获取第二页(10条)按 price 降序排序的产品:
GET /products?page=1&size=10&sortBy=price&direction=desc
  • 1.

结果

Spring Data JPA 会自动处理分页和排序的逻辑,返回的数据将包含分页信息(例如总页数、总记录数等)以及数据本身。

额外提示

  • 你可以根据需要调整分页和排序的字段,支持多种排序方式。
  • PageableSort 是 Spring Data JPA 提供的类,简化了分页和排序的操作。
  • 如果想要更复杂的查询,可以在 Repository 接口中添加自定义方法,比如 findByNameContaining