欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > Spring Boot 中各种分页查询方式完整示例

Spring Boot 中各种分页查询方式完整示例

2025/6/27 0:24:49 来源:https://blog.csdn.net/weixin_40052304/article/details/148553744  浏览:    关键词:Spring Boot 中各种分页查询方式完整示例

在 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 {@Autowiredprivate 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 {@Autowiredprivate UserService userService;@GetMappingpublic 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 {@Autowiredprivate 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 {@Beanpublic 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 {@Autowiredprivate 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 {@Autowiredprivate 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 {@Autowiredprivate 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 {@Autowiredprivate ReactiveUserService userService;@GetMappingpublic 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());}
}

总结

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

  2. MyBatis 分页

    • PageHelper:简单易用

    • MyBatis-Plus:功能更强大

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

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

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

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词