Mybatis插件用于语句执行过程中进行拦截,通过自定义处理程序来拦截和修改SQL语句、映射语句的结果等。 MyBatis的插件机制包括以下三个组件:
- Interceptor(拦截器):定义一个拦截方法Intercept,该方法在执行SQL语句、执行查询、查询结果的映射时会被调用。
 - Invocation(调用):实际上是对被拦截的方法的封装,封装了 Object target、Method method 和 Object[] args 这三个字段。
 - InterceptorChain(拦截器链):对所有的拦截器进行管理,包括将所有的 interceptor 链接成一条链,并在执行 SQL 语句时按顺序调用。
 
正常写sql语句,不用添加limit,不要使用;结尾。 使用PageHelp插件,只需要page, pageSize。 SQL -> PageHelper插件 -> SQL + limit x(偏移量, (page-1)*pageSize), y(查询数量,pageSize);
MyBatis PageHelper 分页插件使用指南
1. 添加依赖
在 pom.xml 中添加 PageHelper 依赖:
            
            
              xml
              
              
            
          
          <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.3</version>
</dependency>
        2. 配置 PageHelper
在 MyBatis 配置文件 mybatis-config.xml 中添加插件配置:
            
            
              xml
              
              
            
          
          <configuration>
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <property name="helperDialect" value="mysql"/>
            <!-- 分页合理化 -->
            <property name="reasonable" value="true"/>
            <!-- 支持通过 Mapper 接口参数来传递分页参数 -->
            <property name="supportMethodsArguments" value="true"/>
            <property name="params" value="count=countSql"/>
        </plugin>
    </plugins>
</configuration>
        如果使用 Java 配置方式,可以这样配置:
            
            
              java
              
              
            
          
          @Configuration
public class MybatisConfig {
    @Bean
    public PageInterceptor pageInterceptor() {
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("helperDialect", "mysql");
        properties.setProperty("reasonable", "true");
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("params", "count=countSql");
        pageInterceptor.setProperties(properties);
        return pageInterceptor;
    }
}
## 3. 使用示例
### 3.1 基本使用方法
```java
// 在查询之前调用 PageHelper.startPage
PageHelper.startPage(pageNum, pageSize);
List<User> users = userMapper.selectAll();
// 获取分页信息
PageInfo<User> pageInfo = new PageInfo<>(users);
        3.2 Service 层示例
            
            
              java
              
              
            
          
          @Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    public PageInfo<User> getUserList(int pageNum, int pageSize) {
        // 设置分页
        PageHelper.startPage(pageNum, pageSize);
        // 查询数据
        List<User> users = userMapper.selectAll();
        // 返回分页信息
        return new PageInfo<>(users);
    }
}
        3.3 Controller 层示例
            
            
              java
              
              
            
          
          @RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/list")
    public PageInfo<User> getUserList(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        return userService.getUserList(pageNum, pageSize);
    }
}
        3.4 Mapper 接口示例
            
            
              java
              
              
            
          
          @Mapper
public interface UserMapper {
    // 不需要在 SQL 中写分页语句
    List<User> selectAll();
}
        3.5 XML 映射文件示例
            
            
              xml
              
              
            
          
          <select id="selectAll" resultType="com.example.entity.User">
    SELECT * FROM user
    <!-- 不需要写 LIMIT 语句,PageHelper 会自动添加 -->
</select>
        4. PageInfo 对象包含的分页信息
- pageNum:当前页码
 - pageSize:每页数量
 - size:当前页的数量
 - total:总记录数
 - pages:总页数
 - list:查询结果
 - prePage:前一页
 - nextPage:下一页
 - isFirstPage:是否为第一页
 - isLastPage:是否为最后一页
 - hasPreviousPage:是否有前一页
 - hasNextPage:是否有下一页
 - navigatePages:导航页码数
 - navigatePageNums:所有导航页号
 
5. 高级用法
5.1 带条件的分页查询
            
            
              java
              
              
            
          
          // Service层
public PageInfo<User> searchUsers(String keyword, int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<User> users = userMapper.searchByKeyword(keyword);
    return new PageInfo<>(users);
}
// Mapper接口
List<User> searchByKeyword(@Param("keyword") String keyword);
// XML映射
<select id="searchByKeyword" resultType="User">
    SELECT * FROM user 
    WHERE username LIKE CONCAT('%', #{keyword}, '%')
</select>
        5.2 排序查询
            
            
              java
              
              
            
          
          // 按年龄降序
PageHelper.startPage(pageNum, pageSize, "age desc");
List<User> users = userMapper.selectAll();
// 多字段排序
PageHelper.startPage(pageNum, pageSize, "age desc, create_time asc");
        5.3 不要分页的情况
            
            
              java
              
              
            
          
          // 使用 PageHelper.clearPage() 清除分页内容
PageHelper.clearPage();
List<User> allUsers = userMapper.selectAll();
        6. 注意事项
- 
线程安全:PageHelper 使用 ThreadLocal 保证线程安全,但要注意在线程池环境下需要清理。
 - 
分页参数合理化:
 
            
            
              yaml
              
              
            
          
          pagehelper:
  reasonable: true  # 当页数小于1时自动查询第一页,大于最后一页时查询最后一页
        - 性能考虑:
 
- 避免使用太大的页码数
 - 合理设置每页数量
 - 对于大数据量建议使用物理分页
 
- Count 查询优化:
 
            
            
              yaml
              
              
            
          
          pagehelper:
  page-size-zero: true  # 当 pageSize=0 时查询所有结果
        7. 常见问题解决
- 分页失效问题:
 
- 确保 PageHelper.startPage() 紧跟着执行查询语句
 - 不要在 PageHelper.startPage() 后进行多次查询
 
- Count 查询优化:
 
            
            
              java
              
              
            
          
          // 设置不进行 count 查询
PageHelper.startPage(pageNum, pageSize, false);
        - 排序问题:
 
            
            
              java
              
              
            
          
          // 使用 PageHelper 的排序功能
String orderBy = "create_time desc";
PageHelper.startPage(pageNum, pageSize).setOrderBy(orderBy);