SpringBoot中各种分页查询方式的示例代码
目录
- 1. Spring Data JPA 分页
- 1.1 基本实现
- 1.2 自定义返回结果
- 2. MyBATis 分页
- 2.1 使用 PageHelper
- 2.2 MyBatis-Plus 分页
- 3. 手动分页
- 4. WebMvc 分页参数自动绑定
- 5. 响应式分页 (WebFlux)
- 总结
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) { Pagjavascripteable 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); } }
Controllandroider 层:
@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, si编程客栈ze)); }
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); javascript 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); Fluandroidx<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分页查询的资料请关注编程客栈(www.devze.com)其它相关文章!
精彩评论