mybatisplus3.5.12 配合pageHelper 分页
时间: 2025-07-05 09:04:29 浏览: 18
<think>我们使用MyBatis-Plus(版本3.5.12)配合PageHelper进行分页。注意:MyBatis-Plus自带分页功能(PaginationInterceptor),但有时项目可能已经使用了PageHelper,因此需要整合使用。然而,MyBatis-Plus和PageHelper的分页原理不同,同时使用可能会产生冲突。通常,我们选择其中一种分页方式。但如果必须同时使用(例如,项目中已有PageHelper分页,但部分功能使用MyBatis-Plus),我们需要确保它们不互相干扰。这里我们提供一种方案:在同一个项目中,我们可以在使用MyBatis-Plus的分页时禁用PageHelper,或者在使用PageHelper时避免使用MyBatis-Plus的分页。但更好的做法是统一使用一种分页方式。不过,如果你确实需要在同一个项目中使用两种分页插件(不推荐),可以尝试以下配置:1.对于PageHelper,我们使用其自带的PageInterceptor(在mybatis-config.xml或Spring配置中配置)。2.对于MyBatis-Plus,我们配置其分页插件PaginationInterceptor(在Spring配置中)。但是,由于两个插件都是通过拦截器实现的,同时使用可能会导致分页参数混乱。因此,我们通常避免同时使用。现在,假设我们统一使用PageHelper进行分页,那么MyBatis-Plus的分页插件就不需要配置。但是,MyBatis-Plus的BaseMapper中的selectPage方法需要分页插件支持,如果不配置,该方法将无法实现物理分页(只会查询全部数据)。因此,如果我们希望使用MyBatis-Plus的BaseMapper的selectPage方法,就需要配置MyBatis-Plus的分页插件,而PageHelper则不需要配置(或者避免在同一个线程中先后调用两个分页插件)。另一种方案是:全部使用PageHelper进行分页,不使用MyBatis-Plus的selectPage方法,而是使用MyBatis-Plus的条件构造器配合PageHelper。这样,我们可以这样操作:步骤:1.在查询前调用PageHelper.startPage方法。2.然后使用MyBatis-Plus的mapper进行查询(使用条件构造器构建查询条件,但不要使用selectPage方法,而是使用selectList或其他方法)。3.查询结果会被PageHelper拦截并分页,然后我们再用PageInfo对结果进行包装。示例代码(SpringBoot环境):首先,确保依赖中包含PageHelper和MyBatis-Plus。配置PageHelper(在application.yml中):```yamlpagehelper:helper-dialect:mysqlreasonable:truesupport-methods-arguments:true```然后,在代码中使用:```javaimportcom.github.pagehelper.PageHelper;importcom.github.pagehelper.PageInfo;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.List;@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredprivateUserMapperuserMapper;//假设UserMapper是MyBatis-Plus的Mapper@OverridepublicPageInfo<User>pageUser(intpageNum,intpageSize){//使用PageHelper.startPagePageHelper.startPage(pageNum,pageSize);//构建查询条件,这里使用MyBatis-Plus的条件构造器QueryWrapper<User>wrapper=newQueryWrapper<>();wrapper.eq("status",1);//例如,查询状态为1的用户//使用MyBatis-Plus的selectList方法,此时会被PageHelper拦截List<User>users=userMapper.selectList(wrapper);//用PageInfo对结果进行包装returnnewPageInfo<>(users);}}```这样,我们就实现了使用PageHelper分页,同时利用MyBatis-Plus的条件构造器。但是,如果我们想使用MyBatis-Plus的分页插件,那么配置如下(在SpringBoot配置类中):```javaimportcom.baomidou.mybatisplus.annotation.DbType;importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassMybatisPlusConfig{@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));returninterceptor;}}```然后,我们可以使用MyBatis-Plus的selectPage方法:```javaimportcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredprivateUserMapperuserMapper;@OverridepublicPage<User>pageUser(intpageNum,intpageSize){Page<User>page=newPage<>(pageNum,pageSize);QueryWrapper<User>wrapper=newQueryWrapper<>();wrapper.eq("status",1);returnuserMapper.selectPage(page,wrapper);}}```但是,请注意:同时配置两个分页插件(PageHelper和MyBatis-Plus的PaginationInnerInterceptor)可能会导致冲突,比如在同一个线程中先后使用两个分页方法时,可能会出现分页参数错乱。因此,建议项目统一使用一种分页方式。如果已经使用了PageHelper,那么就不要配置MyBatis-Plus的分页插件,并且避免使用MyBatis-Plus的selectPage方法,而是使用PageHelper.startPage配合MyBatis-Plus的条件构造器进行查询。总结:MyBatis-Plus3.5.12配合PageHelper分页,我们可以选择只使用其中一种分页方式,避免同时使用。如果必须同时存在,那么需要确保在同一个线程中不要混用两种分页方式。根据上述分析,我们给出两种方案的示例代码。方案一:使用PageHelper分页(不使用MyBatis-Plus的分页插件)方案二:使用MyBatis-Plus分页(配置MyBatis-Plus分页插件,不使用PageHelper)这里我们给出方案一的代码,因为PageHelper在项目中使用广泛,且与MyBatis-Plus的条件构造器结合良好。方案一示例代码(详细):1.配置PageHelper(SpringBootapplication.yml):```yamlpagehelper:helper-dialect:mysqlreasonable:true#分页合理化support-methods-arguments:true```2.服务层代码:```javaimportcom.github.pagehelper.PageHelper;importcom.github.pagehelper.PageInfo;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importjava.util.List;@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredprivateUserMapperuserMapper;publicPageInfo<User>getUsersByPage(intpageNum,intpageSize){//使用PageHelper设置分页参数PageHelper.startPage(pageNum,pageSize);//使用MyBatis-Plus的条件构造器构建查询QueryWrapper<User>queryWrapper=newQueryWrapper<>();queryWrapper.eq("deleted",0);//例如,查询未删除的用户//执行查询,此时会被PageHelper拦截并进行分页List<User>userList=userMapper.selectList(queryWrapper);//将查询结果封装到PageInfo中returnnewPageInfo<>(userList);}}```3.控制层代码示例:```java@RestController@RequestMapping("/user")publicclassUserController{@AutowiredprivateUserServiceuserService;@GetMapping("/list")publicResultlist(@RequestParam(defaultValue="1")intpageNum,@RequestParam(defaultValue="10")intpageSize){PageInfo<User>pageInfo=userService.getUsersByPage(pageNum,pageSize);returnResult.success(pageInfo);}}```注意:PageHelper.startPage(pageNum,pageSize)一定要紧跟在执行查询之前,中间不要有其他的数据库查询,否则会导致分页失效。方案二:使用MyBatis-Plus分页(不配置PageHelper)1.配置MyBatis-Plus分页插件(如上配置类)2.服务层代码:```javaimportcom.baomidou.mybatisplus.extension.plugins.pagination.Page;importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;@ServicepublicclassUserServiceImplimplementsUserService{@AutowiredprivateUserMapperuserMapper;publicPage<User>getUsersByPage(intpageNum,intpageSize){Page<User>page=newPage<>(pageNum,pageSize);QueryWrapper<User>queryWrapper=newQueryWrapper<>();queryWrapper.eq("deleted",0);returnuserMapper.selectPage(page,queryWrapper);}}```3.控制层代码:```java@RestController@RequestMapping("/user")publicclassUserController{@AutowiredprivateUserServiceuserService;@GetMapping("/list")publicResultlist(@RequestParam(defaultValue="1")intpageNum,@RequestParam(defaultValue="10")intpageSize){Page<User>page=userService.getUsersByPage(pageNum,pageSize);returnResult.success(page);}}```选择哪种方案取决于项目需求。如果项目已经大量使用PageHelper,那么方案一更合适;如果是新项目且主要使用MyBatis-Plus,则方案二更简洁。最后,如果确实需要同时使用,那么请确保在同一个线程中不要混用两种分页方式,并且注意分页参数的清除(PageHelper在分页后会自动清除,但MyBatis-Plus的分页参数是放在参数中的,不会影响下一次查询)。但是,混用仍然有风险,不推荐。因此,我们推荐统一使用一种分页方式。§§相关问题§§:1.MyBatis-Plus的分页插件是如何工作的?2.PageHelper分页的原理是什么?3.如何避免MyBatis-Plus和PageHelper同时使用时产生的冲突?4.在SpringBoot中如何配置PageHelper?</think>### MyBatis-Plus 3.5.12 整合 PageHelper 分页解决方案
MyBatis-Plus 自带分页功能,但若需与 PageHelper 整合(如遗留项目迁移或特定需求),需注意两者拦截器机制差异。以下是完整整合方案:
#### 解决方案核心思路
1. **禁用 MyBatis-Plus 分页插件**:避免双重分页冲突
2. **配置 PageHelper 拦截器**:实现物理分页
3. **结合 MyBatis-Plus 条件构造器**:保持其强大的查询功能
#### 步骤 1:添加依赖(pom.xml)
```xml
<!-- MyBatis-Plus 3.5.12 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.12</version>
</dependency>
<!-- PageHelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
```
#### 步骤 2:配置分页插件(禁用 MP 分页)
```java
@Configuration
public class MybatisConfig {
// 禁用 MyBatis-Plus 自带分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 不添加 PaginationInnerInterceptor
return interceptor;
}
// 配置 PageHelper
@Bean
public PageInterceptor pageInterceptor() {
return new PageInterceptor();
}
}
```
#### 步骤 3:Service 层实现分页查询
```java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public PageInfo<User> getUsersByPage(int pageNum, int pageSize) {
// 1. 启动分页 (必须紧接在查询前调用)
PageHelper.startPage(pageNum, pageSize);
// 2. 使用 MyBatis-Plus 条件构造器构建查询
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", 1).orderByDesc("create_time");
// 3. 执行查询 (自动分页)
List<User> userList = userMapper.selectList(queryWrapper);
// 4. 包装为 PageInfo 对象
return new PageInfo<>(userList);
}
}
```
#### 步骤 4:Controller 调用示例
```java
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public Result<PageInfo<User>> getUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
PageInfo<User> pageInfo = userService.getUsersByPage(page, size);
return Result.success(pageInfo);
}
}
```
#### 关键点解释
1. **`PageHelper.startPage()`**:
- 必须紧邻实际查询语句之前调用
- 使用 `PageHelper.offsetPage()` 可实现更灵活的分页控制
2. **`PageInfo` 对象**:
- 包含分页数据及元信息(总页数/当前页/每页数量等)
- 默认导航页码数为 8,可通过 `PageInfo#setNavigatePages` 调整
3. **注意事项**:
- **线程安全问题**:确保分页操作在同一线程内完成
- **分页清除**:调用 `PageHelper.clearPage()` 可手动清除分页设置
- **多数据源**:需配合 `PageHelper.startPage(pageNum, pageSize, true)` 强制 count 查询
#### 分页结果示例(JSON)
```json
{
"data": {
"list": [/* 当前页数据 */],
"pageNum": 1,
"pageSize": 10,
"total": 100,
"pages": 10,
"hasPreviousPage": false,
"hasNextPage": true
}
}
```
### 整合原理说明
1. **PageHelper 拦截器**:
- 通过 `PageInterceptor` 拦截 Executor 的 query 方法
- 自动改写 SQL 添加 `LIMIT` 子句并执行 count 查询
2. **与 MyBatis-Plus 协作**:
- MP 的条件构造器仅生成 WHERE 条件
- PageHelper 负责最终 SQL 的分页处理
- 两者通过 MyBatis 的拦截器链顺序执行
---
阅读全文
相关推荐

















