作者:tan日拱一兵来源:https://blog.csdn.net/yusimiao/article/details/91789384
拦截器介绍
Mybatis Interceptor 在 Mybatis 中被当作 Plugin(插件),不知道为什么,但确实是在 org.apache.ibatis.plugin 包下面。
既然是拦截器,可以拦截哪些内容呢?试想一下...... 当程序写到持久层时,Mybatis 会 执行指定 SQL 语句,并处理 请求参数 和 返回值。没错,Mybatis 拦截器可以帮助我们处理上述内容,请看官网的 Plugins 的片段, 内容不多
// 执行Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)// 请求参数处理ParameterHandler (getParameterObject, setParameters)// 返回结果集处理ResultSetHandler (handleResultSets, handleOutputParameters)// SQL语句构建StatementHandler (prepare, parameterize, batch, update, query)
拦截器的使用
如果需要实现自定义的拦截器,只需要实现 org.apache.ibatis.plugin.Interceptor 接口,该接口有三个方法:
Object intercept(Invocation invocation) throws Throwable;Object plugin(Object target);void setProperties(Properties properties);
我们要实现数据加密,进入数据库的字段不能是真实的数据,但是返回来的数据要真实可用,所以我们需要针对 Parameter 和 ResultSet 两种类型处理,同时为了更灵活的使用,我们需要自定义注解
自定义注解
类注解,将注解放在实体类上
/** * 需要加解密的类注解 */@Documented@Inherited@Target({ ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)public @interface EncryptDecryptClass {}
字段注解,将注解放在实体字段上
/** * 加密字段注解 */@Documented@Inherited@Target({ ElementType.FIELD })@Retention(RetentionPolicy.RUNTIME)public @interface EncryptDecryptField {}
有了这两个注解,我们可以在我们可以标记我们要处理的实体和实体中的字段
自定义参数处理拦截器
参考官网,通过 @Intercepts 和 @Signature 的联合使用,指定 ParameterHandler.class 类型,同时通过 @Component注解注入到容器中,即可在设置参数的时候进行拦截,通过自定义接口 IEncryptDecrypt, 根据 Field 的各种类型自定义加密解密算法
![bb47e84d0f514805b7eaff3606787122.png](https://i-blog.csdnimg.cn/blog_migrate/918716354bf785dc7fca9861e674776c.jpeg)
![26d5c5098ba15355e2145f0f3f065e32.png](https://i-blog.csdnimg.cn/blog_migrate/753c3d6d1b6e78aa1d40dd381150743d.jpeg)
同样新建结果集拦截器
结果集拦截器
与参数拦截器基本一样, 只不过类型指定为 ResultSetHandler.class
![439df4a82e8ba8843adf223bc1b1328e.png](https://i-blog.csdnimg.cn/blog_migrate/a63aecad1454313eb6f85971783f1b26.jpeg)
![0911734667e7c813fc0764e0ba0c9d77.png](https://i-blog.csdnimg.cn/blog_migrate/6b0ed51787f38599c6bd66ef7da5e4ab.jpeg)
加密解密接口
IEncryptDecrypt 接口定义了 加密和解密两个方法:
![93d5e27a091d23bcc84930c56601ffcd.png](https://i-blog.csdnimg.cn/blog_migrate/5327c6b63eceab12ffe209493ed2aff9.jpeg)
两个拦截器通过在 YAML 中配置属性,按条件注入,外加自定义加密解密算法,完成全局灵活的配置。
核心代码已上传至 Github Demo
问题彩蛋
也许应对当前的业务,看了该文章满足了当下需求,我们目前只看到了什么是 Mybatis 拦截器,怎样简单使用,拦截器的其他用法以及其他很多为什么都没有解决,关注公众号,回复“人迹罕至” 读完文章 「程序猿为什么要看源码」后 ,我不会满足眼前的这些基本应用,我会有诸多疑问,
- 我们日常写 CRUD 的业务,为什么 Executor 中只有 R(query) 和 U(update), 那么C(insert) 和 D(delete) 怎样处理的?
- 自定义拦截器是以什么方式被执行的,执行顺序是什么?
- 分页也是 Mybatis 拦截器的一种,带有分页的框架是怎样使用拦截器的呢?如 Mybatis Plus, PageHelper
- 虽然重写了 Inteceptor 接口的 public void setProperties(Properties properties) 方法,但是并没有写什么业务逻辑,这个方法能怎样使用?
- ......
后续文章也会通过读源码的方式逐步解析这些问题,当然你有相关问题也可以留言交流讨论
提高效率工具
依旧推荐在写文章时用到的高效工具,后续相关工具也会在文章中陆续更新,请持续关注
MyBatis Log Plugin
MyBatis Log Plugin 是 Intelligj IDEA 的一个插件,用来从 Mybatis 输出的 log 中提取出当前调用的 SQL 语句,并将参数封装在 SQL 语句中组成完整的 SQL,这样,当我们调试的时候更加清晰方便,可以轻松定位是否 SQL 又问题
![835045bd7dbd98ed7bcbcd8d0de589a6.gif](https://i-blog.csdnimg.cn/blog_migrate/e38457e5de86a371873a79601561f41d.gif)