SpringBoot中各种分页查询方式的示例代码

 更新时间:2025年06月13日 09:00:06   作者:北葵向暖_南栀倾寒  
在 Spring Boot 中,实现分页查询有多种方式,下面小编将介绍几种常见的分页实现方法,包括 Spring Data JPA 分页、MyBatis 分页、手动分页等

1. Spring Data JPA 分页

这是最简单和常用的分页方式,Spring Data JPA 内置了分页支持。

1.1 基本实现

首先,添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

实体类:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    // getters, setters, constructors...
}

Repository 接口:

public interface UserRepository extends JpaRepository<User, Long> {
    Page<User> findByNameContaining(String name, Pageable pageable);
}

Service 层:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public Page<User> getUsersByName(String name, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending());
        return userRepository.findByNameContaining(name, pageable);
    }
}

Controller 层:

@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping
    public ResponseEntity<Page<User>> getUsers(
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return ResponseEntity.ok(userService.getUsersByName(name, page, size));
    }
}

1.2 自定义返回结果

有时我们需要自定义返回数据结构:

public class PageResult<T> {
    private List<T> content;
    private int page;
    private int size;
    private long totalElements;
    private int totalPages;
    // getters, setters...
    
    public static <T> PageResult<T> fromPage(Page<T> page) {
        PageResult<T> result = new PageResult<>();
        result.setContent(page.getContent());
        result.setPage(page.getNumber());
        result.setSize(page.getSize());
        result.setTotalElements(page.getTotalElements());
        result.setTotalPages(page.getTotalPages());
        return result;
    }
}

然后在 Controller 中使用:

@GetMapping("/custom")
public ResponseEntity<PageResult<User>> getUsersCustom(
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {
    Page<User> userPage = userService.getUsersByName(name, page, size);
    return ResponseEntity.ok(PageResult.fromPage(userPage));
}

2. MyBatis 分页

2.1 使用 PageHelper

添加依赖:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>最新版本</version>
</dependency>

Mapper 接口:

@Mapper
public interface UserMapper {
    List<User> findByName(@Param("name") String name);
}

Service 层:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    public PageInfo<User> getUsersByName(String name, int page, int size) {
        PageHelper.startPage(page, size);
        List<User> users = userMapper.findByName(name);
        return new PageInfo<>(users);
    }
}

Controller 层:

@GetMapping("/mybatis")
public ResponseEntity<PageInfo<User>> getUsersMybatis(
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {
    return ResponseEntity.ok(userService.getUsersByName(name, page, size));
}

2.2 MyBatis-Plus 分页

添加依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>最新版本</version>
</dependency>

配置分页插件:

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

Mapper 接口:

public interface UserMapper extends BaseMapper<User> {
    // 继承基本方法
}

Service 层:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    public IPage<User> getUsersByName(String name, int page, int size) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("name", name);
        return userMapper.selectPage(new Page<>(page, size), wrapper);
    }
}

Controller 层:

@GetMapping("/mybatis-plus")
public ResponseEntity<IPage<User>> getUsersMybatisPlus(
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {
    return ResponseEntity.ok(userService.getUsersByName(name, page, size));
}

3. 手动分页

当数据量不大或需要特殊处理时,可以使用手动分页:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public List<User> getUsersManually(String name, int page, int size) {
        List<User> allUsers = userRepository.findByNameContaining(name);
        
        int fromIndex = page * size;
        if (fromIndex >= allUsers.size()) {
            return Collections.emptyList();
        }
        
        int toIndex = Math.min(fromIndex + size, allUsers.size());
        return allUsers.subList(fromIndex, toIndex);
    }
    
    public Map<String, Object> getUsersWithTotal(String name, int page, int size) {
        List<User> allUsers = userRepository.findByNameContaining(name);
        List<User> pageContent = getUsersManually(name, page, size);
        
        Map<String, Object> result = new HashMap<>();
        result.put("content", pageContent);
        result.put("currentPage", page);
        result.put("pageSize", size);
        result.put("totalElements", allUsers.size());
        result.put("totalPages", (int) Math.ceil((double) allUsers.size() / size));
        
        return result;
    }
}

Controller 层:

@GetMapping("/manual")
public ResponseEntity<Map<String, Object>> getUsersManual(
        @RequestParam(required = false) String name,
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "10") int size) {
    return ResponseEntity.ok(userService.getUsersWithTotal(name, page, size));
}

4. WebMvc 分页参数自动绑定

可以创建一个分页参数类来自动绑定分页参数:

public class PageParam {
    @Min(0)
    private int page = 0;
    
    @Min(1)
    @Max(100)
    private int size = 10;
    
    private String sort = "id,asc"; // 格式: field,direction
    
    // getters, setters...
    
    public Pageable toPageable() {
        String[] parts = sort.split(",");
        if (parts.length == 2) {
            return PageRequest.of(page, size, 
                Sort.by(Sort.Direction.fromString(parts[1]), parts[0]));
        }
        return PageRequest.of(page, size);
    }
}

Controller 使用:

@GetMapping("/auto-page")
public ResponseEntity<Page<User>> getUsersAutoPage(
        @RequestParam(required = false) String name,
        PageParam pageParam) {
    return ResponseEntity.ok(userRepository.findByNameContaining(name, pageParam.toPageable()));
}

5. 响应式分页 (WebFlux)

如果使用 Spring WebFlux:

添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Repository:

public interface ReactiveUserRepository extends ReactiveMongoRepository<User, String> {
    Flux<User> findByNameContaining(String name, Pageable pageable);
}

Service:

@Service
public class ReactiveUserService {
    @Autowired
    private ReactiveUserRepository userRepository;
    
    public Mono<Page<User>> getUsers(String name, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Flux<User> userFlux = userRepository.findByNameContaining(name, pageable);
        Mono<Long> countMono = userRepository.countByNameContaining(name);
        
        return Mono.zip(userFlux.collectList(), countMono)
            .map(tuple -> new PageImpl<>(tuple.getT1(), pageable, tuple.getT2()));
    }
}

Controller:

@RestController
@RequestMapping("/api/reactive/users")
public class ReactiveUserController {
    @Autowired
    private ReactiveUserService userService;
    
    @GetMapping
    public Mono<ResponseEntity<Page<User>>> getUsers(
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return userService.getUsers(name, page, size)
            .map(ResponseEntity::ok)
            .defaultIfEmpty(ResponseEntity.notFound().build());
    }
}

总结

Spring Data JPA 分页:最简单,适合大多数 CRUD 应用

1.MyBatis 分页:

  • PageHelper:简单易用
  • MyBatis-Plus:功能更强大

2.手动分页:灵活,适合特殊需求

3.自动绑定分页参数:提高代码整洁度

4.响应式分页:适合响应式应用

根据项目需求和技术栈选择合适的分页方式。对于大多数 Spring Boot 项目,Spring Data JPA 或 MyBatis-Plus 的分页功能已经足够强大且易于使用。

以上就是SpringBoot中各种分页查询方式的示例代码的详细内容,更多关于SpringBoot分页查询的资料请关注脚本之家其它相关文章!

相关文章

  • fastjson对JSONObject中的指定字段重新赋值的实现

    fastjson对JSONObject中的指定字段重新赋值的实现

    这篇文章主要介绍了fastjson对JSONObject中的指定字段重新赋值的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Spring通过c3p0配置bean连接数据库

    Spring通过c3p0配置bean连接数据库

    这篇文章主要为大家详细介绍了Spring通过c3p0配置bean连接数据库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • Java中的System.getenv()和System.getProperty()使用详解

    Java中的System.getenv()和System.getProperty()使用详解

    文章介绍了Java中用于读取环境配置信息的两种方法:System.getenv()和System.getProperty(),前者读取系统环境变量,返回一个不可修改的Map;后者获取JVM环境变量值,可以通过-D参数设置,文章还提到,通过这两种方法可以简化配置,不需要修改代码
    2024-11-11
  • idea指定启动参数、环境变量的过程

    idea指定启动参数、环境变量的过程

    这篇文章主要介绍了idea指定启动参数、环境变量的操作过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • 教你怎么用java一键自动生成数据库文档

    教你怎么用java一键自动生成数据库文档

    最近小编也在找这样的插件,就是不想写文档了,浪费时间和心情啊,果然我找到一款比较好用,操作简单不复杂.screw 是一个简洁好用的数据库表结构文档的生成工具,支持 MySQL、Oracle、PostgreSQL 等主流的关系数据库.需要的朋友可以参考下
    2021-05-05
  • springboot 2.x整合mybatis实现增删查和批量处理方式

    springboot 2.x整合mybatis实现增删查和批量处理方式

    这篇文章主要介绍了springboot 2.x整合mybatis实现增删查和批量处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • mybatis3使用@Select等注解实现增删改查操作

    mybatis3使用@Select等注解实现增删改查操作

    这篇文章主要介绍了mybatis3使用@Select等注解实现增删改查操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Spring中的MultipartFile详解

    Spring中的MultipartFile详解

    这篇文章主要介绍了Spring中的MultipartFile详解,随着Spring框架的崛起,使用Spring框架中的MultipartFile来处理文件也是件很方便的事了,今天就为大家带来剖析MultipartFile的神秘面纱,需要的朋友可以参考下
    2024-01-01
  • 如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    这篇文章主要介绍了如何在Spring Boot应用中优雅的使用Date和LocalDateTime,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • 如何将JSON字符串数组转对象集合

    如何将JSON字符串数组转对象集合

    这篇文章主要介绍了如何将JSON字符串数组转对象集合,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论