当前位置:   article > 正文

MyBatis拦截器-打印出真正执行的sql语句和执行结果_mybatis配置打印查询结果

mybatis配置打印查询结果

目录

广而告之

背景

先看成品

实现步骤

第一步,实现Interceptor接口

​编辑

第二步,给拦截器指定要拦截的方法签名

第三步,实现拦截器的intercept方法。

第四步,在mybatis-config.xml里配置上这个拦截器插件

第五步,禁用mybatis打印日志


广而告之

给大家推荐一个好用的在线工具网站:

常用工具|无忧在线工具

如果我们在学习工作过程中,需要用到时间戳与日期的互转,或JSON在线编辑、格式化、校验JSON格式等功能,建议首选这个常用工具|无忧在线工具

这个网站有极简风格的页面,它的时间戳转换器,可以智能解析多种常见的日期格式。例如“1949-10-01”或“1949/10-01”,原样复制到输入框就可以智能解析。

它下方的JSON编辑器,支持JSON格式、JSON压缩、JSON在线编辑,校验JSON格式等功能。

并且有折叠功能,非常强大。

推荐使用:常用工具|无忧在线工具

背景

MyBatis可以通过xml或注解配置sql模版,程序运行过程中我们可以把参数填充到sql模版里再执行,十分方便。

但是实际生产过程中我们通常会有两个诉求:

  1. 记录填充完参数后,真正执行的sql语句
  2. 自动记录sql执行结果

可以借助MyBatis拦截器实现这一诉求。

先看成品

效果:

拦截器代码:

  1. package org.example.learn.filter;
  2. import com.alibaba.fastjson.JSONObject;
  3. import org.apache.ibatis.executor.statement.StatementHandler;
  4. import org.apache.ibatis.plugin.*;
  5. import org.apache.ibatis.session.ResultHandler;
  6. import java.sql.Statement;
  7. import java.util.Properties;
  8. @Intercepts({
  9. @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
  10. @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})
  11. })
  12. public class InterceptorDome implements Interceptor {
  13. @Override
  14. public Object intercept(Invocation invocation) throws Throwable {
  15. Statement statement = (Statement) invocation.getArgs()[0];
  16. System.out.println("-------------------------------");
  17. System.out.println("sql:"+statement.toString().substring(statement.toString().indexOf(":")+1));
  18. Object result =invocation.proceed();
  19. System.out.println("-------------------------------");
  20. System.out.println("result:"+ JSONObject.toJSONString(result));
  21. return result;
  22. }
  23. @Override
  24. public Object plugin(Object target) {
  25. return Plugin.wrap(target, this);
  26. }
  27. @Override
  28. public void setProperties(Properties properties) {
  29. }
  30. }

插件配置: 

  1. <plugins>
  2. <plugin interceptor="org.example.learn.filter.InterceptorDome">
  3. <property name="test" value="test"/>
  4. </plugin>
  5. </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接口

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的写法吧,读者自行研究一下吧

如果不禁用mybatis打印日志,statement.toString()输出的就是:org.apache.ibatis.logging.jdbc.PreparedStatementLogger@xxx

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/940282
推荐阅读
相关标签
  

闽ICP备14008679号