mybatis插件源码解读

没事看一下mybatis插件源码, 虽然之前时知道原理的,但是时间长了都记不清了, 所以这次直接翻源码看一下, 重新了解一下原理。
SqlMapperConfig.xml中配置了两个插件
在这里插入图片描述
在执行SqlSessionFactory的OpenSession时,需要创建Executor执行器
在这里插入图片描述
这里查看一下newExecutor方法
在这里插入图片描述
发现虽然创建了Executor,但是返回的时interceptorChain.pluginAll包裹的方法,看一下这个interceptorChain.pluginAll干了什么
在这里插入图片描述
ok,这里所有的自定义插件被实例化了,放到interceptors中,然后Executor对象创建后要被所有的自定义插件执行plugin方法包裹一下,这个interceptor.plugin就是我们自定义插件里的plugin方法,一般返回的都是Plugin.wrap()在这里插入图片描述
如果不写的话默认也是Plugin.wrap()
在这里插入图片描述
然后再看一眼这个wrap()方法干了啥在这里插入图片描述
原来是对创建的Executor执行器创建了代理,然后看一下具体的执行
在这里插入图片描述
Plugin类是实现了InvocationHandler接口的,熟悉jdk动态代理的都知道,调用代理类的方法,就是执行这个接口实现类的invoke方法,而代理类的创建就是再wrap方法中创建的。再看下方的invoke方法,这个是调用逻辑,内部执行了interceptor。intercept方法,就是我们自定义插件的内部逻辑,ok,到此插件的原理就搞明白了,就是创建了层层的代理类,然后执行方法时执行我们自定义插件方法的intercept方法逻辑。
Executor创建后返回的时代理类,那StatementHandler,ParameterHandler,ResultHandler呢?肯定也是,随便翻一个出来看一下在这里插入图片描述
嗯,也是!

这样我们就可以自定义插件,再根据需求改执行的sql了。

下面自定义一个插件试试:

@Intercepts({
        @Signature(
                type = StatementHandler.class,
                method = "prepare",
                args =  {Connection.class,Integer.class}
        )
})
public class MyPageInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
                StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
                BoundSql boundSql = statementHandler.getBoundSql();
                String newSql = boundSql.getSql()+" limit 0,2";
                Field sqlField = boundSql.getClass().getDeclaredField("sql");
                sqlField.setAccessible(true);
                sqlField.set(boundSql,newSql);
                return invocation.proceed();
        }
}

尝试效果:
在这里插入图片描述
其实可以翻看一下com.github.pagehelper.PageInterceptor这个类,这个是github开源的分页插件,别人是如何用ThreadLocal缓存分页变量,查询count统计,执行分页逻辑,封装分页结果的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值