点击上方 Java后端,选择 设为星标
优质文章,及时送达
关于Mybatis插件,大部分人都知道,也都使用过,但很多时候,我们仅仅是停留在表面上,知道Mybatis插件可以在DAO层进行拦截,如打印执行的SQL语句日志,做一些权限控制,分页等功能;但对其内部实现机制,涉及的软件设计模式,编程思想往往没有深入的理解。
本篇案例将帮助读者对Mybatis插件的使用场景,实现机制,以及其中涉及的编程思想进行一个小结,希望对以后的编程开发工作有所帮助。
注:本案例以mybatis 3.4.7-SNAPSHOT版本为例。
PS:文章是挺久之前写的,当时花了一些心思,存到电脑的word里,今天正好看到,就是里面的源码都是图片,哈哈哈,凑合着看吧。更多 MyBatis干货,可以关注微信公众号 Java后端 回复 666 下载。
分页功能
mybatis的分页默认是基于内存分页的(查出所有,再截取),数据量大的情况下效率较低,不过使用mybatis插件可以改变该行为,只需要拦截StatementHandler类的prepare方法,改变要执行的SQL语句为分页语句即可;
公共字段统一赋值
一般业务系统都会有创建者,创建时间,修改者,修改时间四个字段,对于这四个字段的赋值,实际上可以在DAO层统一拦截处理,可以用mybatis插件拦截Executor类的update方法,对相关参数进行统一赋值即可;
性能监控
对于SQL语句执行的性能监控,可以通过拦截Executor类的update, query等方法,用日志记录每个方法执行的时间;
其它
其实mybatis扩展性还是很强的,基于插件机制,基本上可以控制SQL执行的各个阶段,如执行阶段,参数处理阶段,语法构建阶段,结果集处理阶段,具体可以根据项目业务来实现对应业务逻辑。
什么是Mybatis插件
与其称为Mybatis插件,不如叫Mybatis拦截器,更加符合其功能定位,实际上它就是一个拦截器,应用代理模式,在方法级别上进行拦截。
支持拦截的方法
-
执行器Executor(update、query、commit、rollback等方法);
-
参数处理器ParameterHandler(getParameterObject、setParameters方法);
-
结果集处理器ResultSetHandler(handleResultSets、handleOutputParameters等方法);
-
SQL语法构建器StatementHandler(prepare、parameterize、batch、update、query等方法);
拦截阶段
-
读取mybatis的xml配置文件信息
-
通过SqlSessionFactoryBuilder创建SqlSessionFactory对象
-
通过SqlSessionFactory获取SqlSession对象
-
执行SqlSession对象的selectList方法,查询结果
-
关闭SqlSession
插件配置信息的加载
-
根据解析到的类信息创建Interceptor对象;
-
调用setProperties方法设置属性变量;
-
添加到Configuration的interceptorChain拦截器链中;
代理对象的生成
拦截逻辑的执行
-
intercept:在此实现自己的拦截逻辑,可从Invocation参数中拿到执行方法的对象,方法,方法参数,从而实现各种业务逻辑, 如下代码所示,从invocation中获取的statementHandler对象即为被代理对象,基于该对象,我们获取到了执行的原始SQL语句,以及prepare方法上的分页参数,并更改SQL语句为新的分页语句,最后调用invocation.proceed()返回结果。
-
plugin:生成代理对象;
-
setProperties:设置一些属性变量;
-
设计模式:代理模式、责任链模式;
-
软件思想:AOP编程思想,降低模块间的耦合度,使业务模块更加独立;
-
不要定义过多的插件,代理嵌套过多,执行方法的时候,比较耗性能;
-
拦截器实现类的intercept方法里最后不要忘了执行invocation.proceed()方法,否则多个拦截器情况下,执行链条会断掉;
如果看到这里,说明你喜欢这篇文章,请 转发、点赞。同时 标星(置顶)本公众号可以第一时间接受到博文推送。
推荐阅读
1. 快速创建 Spring Cloud 应用的 Spring Initializr
2. 互联网大厂的后端技术栈
3. 强烈推荐 16 款 IDEA 插件
4. Shiro框架:认证和授权原理
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。