赞
踩
目录
第四步,在mybatis-config.xml里配置上这个拦截器插件
给大家推荐一个好用的在线工具网站:
如果我们在学习工作过程中,需要用到时间戳与日期的互转,或JSON在线编辑、格式化、校验JSON格式等功能,建议首选这个常用工具|无忧在线工具。
这个网站有极简风格的页面,它的时间戳转换器,可以智能解析多种常见的日期格式。例如“1949-10-01”或“1949/10-01”,原样复制到输入框就可以智能解析。
它下方的JSON编辑器,支持JSON格式、JSON压缩、JSON在线编辑,校验JSON格式等功能。
并且有折叠功能,非常强大。
推荐使用:常用工具|无忧在线工具
MyBatis可以通过xml或注解配置sql模版,程序运行过程中我们可以把参数填充到sql模版里再执行,十分方便。
但是实际生产过程中我们通常会有两个诉求:
可以借助MyBatis拦截器实现这一诉求。
效果:
拦截器代码:
- package org.example.learn.filter;
-
- import com.alibaba.fastjson.JSONObject;
- import org.apache.ibatis.executor.statement.StatementHandler;
- import org.apache.ibatis.plugin.*;
- import org.apache.ibatis.session.ResultHandler;
-
- import java.sql.Statement;
- import java.util.Properties;
-
- @Intercepts({
- @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
- @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})
- })
- public class InterceptorDome implements Interceptor {
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- Statement statement = (Statement) invocation.getArgs()[0];
- System.out.println("-------------------------------");
- System.out.println("sql:"+statement.toString().substring(statement.toString().indexOf(":")+1));
- Object result =invocation.proceed();
- System.out.println("-------------------------------");
- System.out.println("result:"+ JSONObject.toJSONString(result));
- return result;
- }
-
- @Override
- public Object plugin(Object target) {
- return Plugin.wrap(target, this);
- }
-
- @Override
- public void setProperties(Properties properties) {
-
- }
- }
插件配置:
- <plugins>
- <plugin interceptor="org.example.learn.filter.InterceptorDome">
- <property name="test" value="test"/>
- </plugin>
- </plugins>
禁用mybatis打印日志:
springboot项目中,在application.properties文件中添加配置:
mybatis.configuration.log-impl=org.apache.ibatis.logging.nologging.NoLoggingImpl
如果不禁用mybatis打印日志,statement.toString()输出的就是:org.apache.ibatis.logging.jdbc.PreparedStatementLogger@xxx
Interceptor接口是mybatis用来实现插件功能的拦截器接口,他有三个方法,
先看setProperties方法,在xml中配置插件时,用<property>标签配置的参数会存储在setProperties方法的参Properties里,可以通过参数来改变拦截器的行为。
然后看plugin方法,这个方法的参数target就是要拦截的对象,该方法的实现很简单,固定用“return Plugin.wrap(target, this)”实现即可。
最后一个方法intercept,是我们主要关注的拦截方法。后面会讲这个方法怎么实现。
回顾java方法签名有哪几个要素:方法所在的类、方法名、方法参数的顺序和类型。
按上图中的方式,用@Intercepts注解和@Signature属性来指定好要拦截的方法签名就可以了。可以指定多个方法签名。
拦截器可以被拦截方法都在这四个接口里:StatementHandler、Executor、ResultSetHandler、ParameterHandler。
这里只讲两个方法:StatementHandler.update和StatementHandler.update
int update(Statement var1)方法会在所有的 INSERT UPDATE DELET 执行时被调用,因此如果想要拦截这类操作,可以拦截该方法。
<E> List<E> query(Statement var1, ResultHandler var2)方法会在SELECT 查询方法执行时被调用。
拦截了这两个方法就拦截了日常工作中大部分被执行的sql 。
invocation.getArgs()方法可以获取被拦截方法的参数数组,由方法签名可知,我们要拦截的两个方法的第一个参数都是Statement,所以获取参数数组第一个元素后,可以直接强转为Statement类型。
此时的Statement已经将sql模版与参数组装好了,直接调用statement.toString()方法就能得到真正执行的sql。
调用invocation.proceed()方法会就会执行被拦截的方法,该方法的返回就是sql执行结果,转换为json字符串打印出来就可以了。
springboot项目中,在application.properties文件中添加配置:
mybatis.configuration.log-impl=org.apache.ibatis.logging.nologging.NoLoggingImpl
我没有找到上面的配置在xml的写法吧,读者自行研究一下吧
如果不禁用mybatis打印日志,statement.toString()输出的就是:org.apache.ibatis.logging.jdbc.PreparedStatementLogger@xxx
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。