Mybatis spring plugin详解

1.环境

  • jdk8
  • mybatis3.5.2
  • Spring 5.1.9.RELEASE
  • spring-jdbc 5.1.9.RELEASE

2.官方解释

mybatis允许自定义拦截执行对数据库操作方法,默认mybatis-plugin支持拦截以下方法:

  • org.apache.ibatis.executor.Executor中定义(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)方法
  • org.apache.ibatis.executor.parameter.ParameterHandler中定义(getParameterObject, setParameters)方法
  • org.apache.ibatis.executor.resultset.ResultSetHandler中定义(handleResultSets, handleOutputParameters)方法
  • org.apache.ibatis.executor.statement.StatementHandler中定义 (prepare, parameterize, batch, update, query)方法

以上类中方法通过方法签名进行拦截,要明白覆盖这些方法功能,假如要监控这些方法,需要修改默认方法行为和重写方法功能,增加拦截器可能破坏mybatis核心代码,增加拦截器代码需要小心

3.plugin配置

3.1 .plugin代码

@Intercepts({@Signature( type = Executor.class, method = "update",
                args = {MappedStatement.class,Object.class}),
        @Signature(
                type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
            @Signature(type = Executor.class, method = "query",
                args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }),
            @Signature(type = Executor.class, method = "query",
                args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class })
})
public class ExamplePlugin implements Interceptor
{
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("拦截开始====");
        Object returnObject = invocation.proceed();
        System.out.println("拦截结束====");
        return returnObject;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

3.2. spring中配置



    

        

        

        

        
    

    
        
            
                sqlserver
                db2
                oracle
                mysql
            
        
    

    
        
    
    
    
        
        


        
        
        
        
            
                
            
        
    

    
    
        
        
    


3.3.测试代码

public class MbatisSpringTest
{
    public static void main( String[] args )
    {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
        BlogMapper blogMapper = ctx.getBean(BlogMapper.class);
//        blogMapper.selectBlog(1);

        blogMapper.containsKey("ttt");
    }
}

3.4.plugin源码分析

3.4.1自定义配置plugin初始化代码片段如下:

org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory


  protected SqlSessionFactory buildSqlSessionFactory() throws Exception {

    final Configuration targetConfiguration;

    …………………………
    //此处代码增加自定义plugin到config中
    if (!isEmpty(this.plugins)) {
      Stream.of(this.plugins).forEach(plugin -> {
        targetConfiguration.addInterceptor(plugin);
        LOGGER.debug(() -> "Registered plugin: '" + plugin + "'");
      });
    }
………………

    return this.sqlSessionFactoryBuilder.build(targetConfiguration);
  }


4.plugin执行流程

Mybatis spring plugin详解_第1张图片
mybatis-plugin-01.png
Mybatis spring plugin详解_第2张图片
mybatis-plugin-02.png

下面两张图是一起,03图后续流程04图接着,一张图放不下,所以分开


Mybatis spring plugin详解_第3张图片
mybatis-plugin-03.png
Mybatis spring plugin详解_第4张图片
mybatis-plugin-04.png

5.plugin相关类说明

org.apache.ibatis.plugin.Interceptor:插件接口,自定义plugin需要实现

org.apache.ibatis.plugin.InterceptorChain:用list保存配置plugin,初始化在org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory

org.apache.ibatis.plugin.Intercepts:自定plugin类中,说明要拦截方法

org.apache.ibatis.plugin.Plugin:判断执行sql方法是不是在自定义plugin规则中,如果存在自动生成代理包含改插件,不存在不包含。

org.apache.ibatis.executor.Executor:配置org.apache.ibatis.plugin.Signature中,进行要拦截方法

你可能感兴趣的:(Mybatis spring plugin详解)