目录
广而告之
背景
先看成品
实现步骤
第一步,实现Interceptor接口
编辑
第二步,给拦截器指定要拦截的方法签名
第三步,实现拦截器的intercept方法。
第四步,在mybatis-config.xml里配置上这个拦截器插件
第五步,禁用mybatis打印日志
广而告之
给大家推荐一个好用的在线工具网站:
常用工具|无忧在线工具
如果我们在学习工作过程中,需要用到时间戳与日期的互转,或JSON在线编辑、格式化、校验JSON格式等功能,建议首选这个常用工具|无忧在线工具。
这个网站有极简风格的页面,它的时间戳转换器,可以智能解析多种常见的日期格式。例如“1949-10-01”或“1949/10-01”,原样复制到输入框就可以智能解析。
它下方的JSON编辑器,支持JSON格式、JSON压缩、JSON在线编辑,校验JSON格式等功能。
并且有折叠功能,非常强大。
推荐使用:常用工具|无忧在线工具
背景
MyBatis可以通过xml或注解配置sql模版,程序运行过程中我们可以把参数填充到sql模版里再执行,十分方便。
但是实际生产过程中我们通常会有两个诉求:
- 记录填充完参数后,真正执行的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文章来源地址https://www.toymoban.com/news/detail-424796.html
实现步骤
第一步,实现Interceptor接口
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 。
第三步,实现拦截器的intercept方法。
invocation.getArgs()方法可以获取被拦截方法的参数数组,由方法签名可知,我们要拦截的两个方法的第一个参数都是Statement,所以获取参数数组第一个元素后,可以直接强转为Statement类型。
此时的Statement已经将sql模版与参数组装好了,直接调用statement.toString()方法就能得到真正执行的sql。
调用invocation.proceed()方法会就会执行被拦截的方法,该方法的返回就是sql执行结果,转换为json字符串打印出来就可以了。
第四步,在mybatis-config.xml里配置上这个拦截器插件
第五步,禁用mybatis打印日志
springboot项目中,在application.properties文件中添加配置:
mybatis.configuration.log-impl=org.apache.ibatis.logging.nologging.NoLoggingImpl
我没有找到上面的配置在xml的写法吧,读者自行研究一下吧文章来源:https://www.toymoban.com/news/detail-424796.html
如果不禁用mybatis打印日志,statement.toString()输出的就是:org.apache.ibatis.logging.jdbc.PreparedStatementLogger@xxx
到了这里,关于MyBatis拦截器-打印出真正执行的sql语句和执行结果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!