1、分页插件
自定义分页插件
分页插件使用
PageHelper 原理
2、mybatis逆向工程
1、分页插件
MyBatis 通过提供插件机制,让我们可以根据自己的需要去增强MyBatis 的功能。需要注意的是,如果没有完全理解MyBatis 的运行原理和插件的工作方式,最好不要使用插件,因为它会改变系底层的工作逻辑,给系统带来很大的影响。
MyBatis 的插件可以在不修改原来的代码的情况下,通过拦截的方式,改变四大核心 对象的行为,比如处理参数,处理SQL,处理结果。
Mybatis插件典型适用场景
分页功能
mybatis的分页默认是基于内存分页的(查出所有,再截取),数据量大的情况下效率较低,不过使用mybatis插件可以改变该行为,只需要拦截StatementHandler类的prepare方法,改变要执行的SQL语句为分页语句即可;
公共字段统一赋值
一般业务系统都会有创建者,创建时间,修改者,修改时间四个字段,对于这四个字段的赋值,实际上可以在DAO层统一拦截处理,可以用mybatis插件拦截Executor类的update方法,对相关参数进行统一赋值即可;
性能监控
对于SQL语句执行的性能监控,可以通过拦截Executor类的update, query等方法,用日志记录每个方法执行的时间;
其它
其实mybatis扩展性还是很强的,基于插件机制,基本上可以控制SQL执行的各个阶段,如执行阶段,参数处理阶段,语法构建阶段,结果集处理阶段,具体可以根据项目业务来实现对应业务逻辑。
实现思考:
第一个问题:
不修改对象的代码,怎么对对象的行为进行修改,比如说在原来的方法前面做一点事情,在原来的方法后面做一点事情?
答案:大家很容易能想到用代理模式,这个也确实是MyBatis 插件的原理。
第二个问题:
我们可以定义很多的插件,那么这种所有的插件会形成一个链路,比如我们提交一个休假申请,先是项目经理审批,然后是部门经理审批,再是HR 审批,再到总经理审批,怎么实现层层的拦截?
答案:插件是层层拦截的,我们又需要用到另一种设计模式——责任链模式。
在之前的源码中我们也发现了,mybatis内部对于插件的处理确实使用的代理模式,既然是代理模式,我们应该了解MyBatis 允许哪些对象的哪些方法允许被拦截,并不是每一个运行的节点都是可以被修改的。只有清楚了这些对象的方法的作用,当我们自己编写插件的时候才知道从哪里去拦截。在MyBatis 官网有答案,我们来看一下:
https://mybatis.org/mybatis-3/zh/configuration.html#plugins
Executor 会拦截到CachingExcecutor 或者BaseExecutor。因为创建Executor 时是先创建CachingExcecutor,再包装拦截。从代码顺序上能看到。我们可以通过mybatis的分页插件来看看整个插件从包装拦截器链到执行拦截器链的过程。
在查看插件原理的前提上,我们需要来看看官网对于自定义插件是怎么来做的,官网上有介绍:通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。这里本人踩了一个坑,在Springboot中集成,同时引入了pagehelperspringbootstarter 导致RowBounds参数的值被刷掉了,也就是走到了我的拦截其中没有被设置值,这里需要注意,拦截器出了问题,可以Debug看一下Configuration配置类中拦截器链的包装情况。
自定义分页插件
1
2 /***
3 * @Author 徐庶 QQ:1092002729
4 * @Slogan 致敬大师,致敬未来的你
5 *
6 * 自定义分页插件实现的简易版分页插件
7 */
8 @Intercepts({
9 @Signature(type = Executor.class,method = "query" ,args ={ MappedStatemen
t.class, Object.class, RowBounds.class</