深入理解Mybatis插件开发

关于Mybatis插件,大部分人都知道,也都使用过,但很多时候,我们仅仅是停留在表面上,知道Mybatis插件可以在DAO层进行拦截,如打印执行的SQL语句日志,做一些权限控制,分页等功能;但对其内部实现机制,涉及的软件设计模式,编程思想往往没有深入的理解。

本篇案例将帮助读者对Mybatis插件的使用场景,实现机制,以及其中涉及的编程思想进行一个小结,希望对以后的编程开发工作有所帮助。

注:本案例以mybatis 3.4.7-SNAPSHOT版本为例。

PS:挺久之前写的,花了一些心思,就是里面的源码都是图片,哈哈哈,凑合着看吧。

Mybatis插件典型适用场景 分页功能

mybatis的分页默认是基于内存分页的(查出所有,再截取),数据量大的情况下效率较低,不过使用mybatis插件可以改变该行为,只需要拦截StatementHandler类的prepare方法,改变要执行的SQL语句为分页语句即可;

公共字段统一赋值

一般业务系统都会有创建者,创建时间,修改者,修改时间四个字段,对于这四个字段的赋值,实际上可以在DAO层统一拦截处理,可以用mybatis插件拦截Executor类的update方法,对相关参数进行统一赋值即可;

性能监控

对于SQL语句执行的性能监控,可以通过拦截Executor类的update, query等方法,用日志记录每个方法执行的时间;

其它

其实mybatis扩展性还是很强的,基于插件机制,基本上可以控制SQL执行的各个阶段,如执行阶段,参数处理阶段,语法构建阶段,结果集处理阶段,具体可以根据项目业务来实现对应业务逻辑。

Mybatis插件介绍 什么是Mybatis插件

与其称为Mybatis插件,不如叫Mybatis拦截器,更加符合其功能定位,实际上它就是一个拦截器,应用代理模式,在方法级别上进行拦截。

支持拦截的方法

执行器Executor(update、query、commit、rollback等方法);

参数处理器ParameterHandler(getParameterObject、setParameters方法);

结果集处理器ResultSetHandler(handleResultSets、handleOutputParameters等方法);

SQL语法构建器StatementHandler(prepare、parameterize、batch、update、query等方法);

拦截阶段

那么这些类上的方法都是在什么阶段被拦截的呢?为理解这个问题,我们先看段简单的代码(摘自mybatis源码中的单元测试SqlSessionTest类),来了解下典型的mybatis执行流程,如下代码所示:

深入理解Mybatis插件开发

以上代码主要完成以下功能:

读取mybatis的xml配置文件信息

通过SqlSessionFactoryBuilder创建SqlSessionFactory对象

通过SqlSessionFactory获取SqlSession对象

执行SqlSession对象的selectList方法,查询结果

关闭SqlSession

如下是时序图,在整个时序图中,涉及到mybatis插件部分已标红,基本上就是体现在上文中提到的四个类上,对这些类上的方法进行拦截。

深入理解Mybatis插件开发

Mybatis插件实现机制 插件配置信息的加载

先来看下mybatis是如何加载插件配置的,对应的xml配置信息如下:

深入理解Mybatis插件开发

对应的解析代码如下,主要做以下工作:

根据解析到的类信息创建Interceptor对象;

调用setProperties方法设置属性变量;

添加到Configuration的interceptorChain拦截器链中;

深入理解Mybatis插件开发

以上逻辑对应的时序图如下:

深入理解Mybatis插件开发

代理对象的生成

Mybatis插件的实现机制主要是基于动态代理实现的,其中最为关键的就是代理对象的生成,所以有必要来了解下这些代理对象是如何生成的。

Executor代理对象

深入理解Mybatis插件开发

ParameterHandler代理对象

深入理解Mybatis插件开发

ResultSetHandler代理对象

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzxjp.html