美文网首页
Mybatis原理

Mybatis原理

作者: ChandlerQian | 来源:发表于2021-02-20 14:52 被阅读0次

    1Mybatis插件介绍

    Mybati s作为⼀个应⽤⼴泛的优秀的ORM开源框架,这个框架具有强⼤的灵活性,在四⼤组件(Executor、StatementHandler、ParameterHandler、ResultSetHandler)处提供了简单易⽤的插 件扩展机制。Mybatis对持久层的操作就是借助于四⼤核⼼对象。MyBatis⽀持⽤插件对四⼤核⼼对象进 ⾏拦截,对mybatis来说插件就是拦截器,⽤来增强核⼼对象的功能,增强功能本质上是借助于底层的 动态代理实现的,换句话说,MyBatis中的四⼤对象都是代理对象


    image.png

    2 Mybatis插件原理

    MyBatis所允许拦截的⽅法如下:
    执⾏器Executor (update、query、commit、rollback等⽅法);
    SQL语法构建器StatementHandler (prepare、parameterize、batch、updates query等⽅ 法);
    参数处理器ParameterHandler (getParameterObject、setParameters⽅法);
    结果集处理器ResultSetHandler (handleResultSets、handleOutputParameters等⽅法);

    Mybatis插件原理
    在四⼤对象创建的时候
    1、每个创建出来的对象不是直接返回的,⽽是interceptorChain.pluginAll(parameterHandler);
    2、获取到所有的Interceptor (拦截器)(插件需要实现的接⼝);调⽤ interceptor.plugin(target);返 回 target 包装后的对象
    3、插件机制,我们可以使⽤插件为⽬标对象创建⼀个代理对象;AOP (⾯向切⾯)我们的插件可 以
    为四⼤对象创建出代理对象,代理对象就可以拦截到四⼤对象的每⼀个执⾏;
    拦截
    插件具体是如何拦截并附加额外的功能的呢?以ParameterHandler来说

    
        public ParameterHandler newParameterHandler(MappedStatement mappedStatement,
                                                    Object object, BoundSql sql, InterceptorChain interceptorChain) {
            ParameterHandler parameterHandler =
                    mappedStatement.getLang().createParameterHandler(mappedStatement, object, sql);
            parameterHandler = (ParameterHandler)
                    interceptorChain.pluginAll(parameterHandler);
            return parameterHandler;
        }
    
        public Object pluginAll(Object target) {
            for (Interceptor interceptor : interceptors) {
                target = interceptor.plugin(target);
            }
            return target;
        }
    

    interceptorChain保存了所有的拦截器(interceptors),是mybatis初始化的时候创建的。调⽤拦截器链中的拦截器依次的对⽬标进⾏拦截或增强。interceptor.plugin(target)中的target就可以理解为mybatis中的四⼤对象。返回的target是被重重代理后的对象.
    如果我们想要拦截Executor的query⽅法,那么可以这样定义插件:

    @Intercepts({
    @Signature(
    type = Executor.class,
    method = "query",
    args= {MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class} )
    })
    public class ExeunplePlugin implements Interceptor {
    //省略逻辑
    }
    

    这样MyBatis在启动时可以加载插件,并保存插件实例到相关对象(InterceptorChain,拦截器链) 中。待准备⼯作做完后,MyBatis处于就绪状态。我们在执⾏SQL时,需要先通过DefaultSqlSessionFactory创建 SqlSession。Executor 实例会在创建 SqlSession 的过程中被创建, Executor实例创建完毕后,MyBatis会通过JDK动态代理为实例⽣成代理类。这样,插件逻辑即可在 Executor相关⽅法被调⽤前执⾏。

    相关文章

      网友评论

          本文标题:Mybatis原理

          本文链接:https://www.haomeiwen.com/subject/gmatfltx.html