Mybatis经常使用用法之 Mybatis插件原理

这是我参与更文挑战的第3天,活动详情查看: 更文挑战web

一:背景

通常状况下,开源框架都会提供插件或其余形式的拓展点,供开发者自行拓展。这样的好处是显而易见的,一是增长了框架的灵活性。二是开发者能够结合实际需求,对框架进行拓展,使其可以更好的工做。以MyBatis为例,咱们可基于MyBatis插件机制实现分页、分表,监控等功能。因为插件和业务无关,业务也没法感知插件的存在。所以能够无感植入插件,在无形中加强功能sql

二:Mybatis插件介绍

Mybatis做为一个应用普遍的优秀的ORM开源框架,这个框架具备强大的灵活性,在四大组件 (Executor、StatementHandler、ParameterHandler、ResultSetHandler)处提供了简单易用的插件扩展机制。Mybatis对持久层的操做就是借助于四大核心对象。MyBatis支持用插件对四大核心对象进行拦截,对mybatis来讲插件就是拦截器,用来加强核心对象的功能,加强功能本质上是借助于底层的 动态代理实现的,换句话说,MyBatis中的四大对象都是代理对象markdown

MyBatis所容许拦截的方法以下:mybatis

  • 执行器Executor (update、query、commit、rollback等方法);
  • SQL语法构建器StatementHandler (prepare、parameterize、batch、updates query等方法);
  • 参数处理器ParameterHandler (getParameterObject、setParameters方法);
  • 结果集处理器ResultSetHandler (handleResultSets、handleOutputParameters等方法);

三:Mybatis插件原理

在四大对象建立的时候app

  • 一、每一个建立出来的对象不是直接返回的,而interceptorChain.pluginAll(parameterHandler);
  • 二、获取到全部的Interceptor (拦截器)(插件须要实现的接口);调用 interceptor.plugin(target);返回 target 包装后的对象
  • 三、插件机制,咱们可使用插件为目标对象建立一个代理对象;AOP (面向切面)咱们的插件能够为四大对象建立出代理对象,代理对象就能够拦截到四大对象的每个执行;

拦截框架

插件具体是如何拦截并附加额外的功能的呢?以ParameterHandler来讲post

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是被重重代理后的对象ui

若是咱们想要拦截Executor的query方法,那么能够这样定义插件:url

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

除此以外,咱们还需将插件配置到sqlMapConfig.xml中。spa

<plugins>
    <plugin interceptor="com.lagou.plugin.ExamplePlugin"></plugin>
</plugins>
复制代码

这样MyBatis在启动时能够加载插件,并保存插件实例到相关对象(InterceptorChain,拦截器链) 中。待准备工做作完后,MyBatis处于就绪状态。咱们在执行SQL时,须要先经过DefaultSqlSessionFactory 创 建 SqlSession。Executor 实例会在建立 SqlSession 的过程当中被建立, Executor实例建立完毕后, MyBatis会经过JDK动态代理为实例生成代理类。这样,插件逻辑便可在 Executor相关方法被调用前执行。

以上就是MyBatis插件机制的基本原理.

但愿对各位小伙伴有所帮助

相关文章
相关标签/搜索