mybatis 分析五 插件demo及源码解析

时间秒杀一切 提交于 2020-12-11 02:03:25

一、新建自定义插件类   简单打印一下sql

/**
 * 打印sql 插件
 */
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class}) })

public class PrintSqlInterceptor implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
       
        //Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
        //ParameterHandler (getParameterObject, setParameters)
        //ResultSetHandler (handleResultSets, handleOutputParameters)
        //StatementHandler (prepare, parameterize, batch, update, query)
        StatementHandler  target = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = target.getBoundSql();
        System.out.println("------------------"+boundSql.getSql()+"--------------");
        return invocation.proceed();
    }
    //创建代理对象

    @Override
    public Object plugin(Object target) {
        System.out.println(target.getClass().getName());
        return Plugin.wrap(target, this);
    }

    //设置插件属性值
    @Override
    public void setProperties(Properties properties) {
        System.out.println("------------------"+properties+"--------------");
    }
}

二、再mybatis.xml配置文件中配置 自定义的插件

 <plugins>
        <plugin interceptor="com.xiao.mybati.PrintSqlInterceptor">
            <property name="dialect" value="mysql"></property>
        </plugin>
    </plugins>

<?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.xiao.mybati.PrintSqlInterceptor">
            <property name="dialect" value="mysql"></property>
        </plugin>
    </plugins>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/casdb?serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/OrderMapper.xml"/>
    </mappers>
</configuration>

 

mybatis 插件源码解析

再解析mybatis.xml配置文件时 会解析plugins 标签 把所有plugin标签配置的interceptor值都解析出来并实例化放到configuration对象里

再获取SqlSession时 SqlSession sqlSession = sqlSessionFactory.openSession(); 会执行所有Interceptor的plugin方法  给 CachingExecutor 执行器创建代理对象

给 CachingExecutor 执行器创建代理对象

再执行SqlSession查询时  Order o = sqlSession.selectOne("com.xiao.mapper.OrderMapper.selectOrder","106");

为parameterHandler和resultSetHandler创建代理对象

为StatementHandler创建代理对象

执行的是StatementHandler代理对象的prepare 方法

最终调用Plugin#invoke方法

最终调到我们自定义的插件方法

 

注:

        mybatis 插件可以lanjie以下对象  可以配置在以下类的方法之前做一些额外的操作
        Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
        ParameterHandler (getParameterObject, setParameters)
        ResultSetHandler (handleResultSets, handleOutputParameters)
        StatementHandler (prepare, parameterize, batch, update, query)

配置规则 再自定义的插件类上加如下注解

@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class}),@Signature(type = ParameterHandler.class, method = "setParameters", args = { PreparedStatement.class}) })

type 要处理哪个类

method  处理type类的 哪个方法

args  方法需要的参数类型

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!