MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

Mybatis-Plus 插件机制(mybatis插件原理)

2025-06-18 21:23 huorong 精选文章 4 ℃ 0 评论

MyBatis Plus提供了分页插件PaginationInterceptor、执行分析插件SqlExplainInterceptor、性能分析插件PerformanceInterceptor以及乐观锁插件OptimisticLockerInterceptor。

Mybatis 通过插件 (Interceptor) 可以做到拦截四大对象相关方法的执行 ,根据需求完成相关数据的动态改变。

四大对象是:

  • Executor(拦截执行器的方法
  • StatementHandler(拦截 Sql 语法构建的处理
  • ParameterHandler(拦截参数的处理
  • ResultSetHandler(拦截结果集的处理

1、分页插件

分页插件,全类名是
com.baomidou.mybatisplus.plugins.PaginationInterceptor,用于支持查询分页功能。可以设置参数,如最大单页限制数量等。

SpringBoot 配置:

@Bean
public PaginationInterceptor paginationInterceptor() {
  return new PaginationInterceptor();
}

xml 方式:

<bean class="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></bean>

2、执行分析插件

SQL执行分析拦截器,全类名是
com.baomidou.mybatisplus.plugins.SqlExplainInterceptor,只支持 MySQL5.6.3以上版本。该插件的作用是分析 DELETE和UPDATE语句 ,防止小白或者恶意进行全表更新、删除操作,不建议在生产环境中使用会造成性能下降,在插件的底层通过SQL语句分析命令 Explain 分析当前的 SQL语句,根据结果集中的 Extra列来断定当前是否全表操作。

SpringBoot 配置:

@Bean
    public SqlExplainInterceptor sqlExplainInterceptor() {
        SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();
        List<ISqlParser> sqlParserList = new ArrayList<>();
        // 攻击 SQL 阻断解析器、加入解析链
        sqlParserList.add(new BlockAttackSqlParser());
        sqlExplainInterceptor.setSqlParserList(sqlParserList);
        return sqlExplainInterceptor;
    }

xml 方式:

<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor">
		<property name="stopProceed" value="true"></property>
</bean>

3、性能分析插件

性能分析拦截器,全类名是
com.baomidou.mybatisplus.plugins.PerformanceInterceptor,用于输出每条 SQL 语句及其执行时间。SQL性能执行分析 ,开发环境使用超过指定时间,停止运行。

SpringBoot 配置:

@Bean
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(100);
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

xml 方式:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<plugins>
 		<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时 -->
     <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor">
         <property name="maxTime" value="100" />
         <!--SQL是否格式化 默认false-->
         <property name="format" value="true" />
     </plugin>
 </plugins>
</configuration>

4、乐观锁插件

全类名是
com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor。如果想实现如下需求 : 当要更新一条记录的时候,希望这条记录没有被别人更新,就可以使用该插件进行判断。

乐观锁的实现原理(@Version 用于注解实体字段,必须要有) :

  • 取出记录时,获取当前 version
  • 更新时,带上这个version
  • 执行更新时,set version = yourVersion+1 where version = yourVersion
  • 如果 version不对,就更新失败

4.1、插件配置

SpringBoot 配置:

@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
  return new OptimisticLockerInterceptor();
}

xml 方式:

<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>

4.2、注解实体字段

需要为实体字段添加 @Version 注解。

第一步,为表添加 version 字段,并且设置初始值为 1 :

ALTER TABLE `tb_user` ADD COLUMN `version` int(10) NULL AFTER `email`;
UPDATE `tb_user` SET `version`='1';

第二步,为User实体对象添加version字段,并且添加@Version注解:

@Version
private Integer version;

4.3 测试用例

@Test
    public void testUpdateVersion(){
        User user = new User();
        user.setAge(30);
        user.setId(2L);
        user.setVersion(1); //获取到version为1
        int result = this.userMapper.updateById(user);
        System.out.println("result = " + result);
    }


更新前:

更新后:

4.4、特别说明

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity 中
  • 仅支持 updateById(id) 与 update(entity, wrapper) 方法
  • 在 update(entity, wrapper) 方法下, wrapper 不能复用!

5、自定义拦截器

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;

import java.util.Properties;
@Intercepts({@Signature(
        type = Executor.class,
        method = "update",
        args = {MappedStatement.class, Object.class})})
public class MyInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //拦截方法,具体业务逻辑编写的位置
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        //创建target对象的代理对象,目的是将当前拦截器加入到该对象中
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        //属性设置
    }
}

注入到Spring容器:

/**
     * 自定义拦截器
     */
    @Bean
    public MyInterceptor myInterceptor(){
        return new MyInterceptor();
    }

xml配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
     <plugins>
          <plugin interceptor="com.lagou.mp.plugins.MyInterceptor"></plugin>
     </plugins>
</configuration>

Tags:mybatisplus清空表数据

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言