前言

mybatisplus在mybatis的基础上为我们提供了诸多方便,大大加快了开发的速率,但是在日常工作中,还是会发现有一些不方便之处,那就是关于日志的打印,框架虽然也提供了日志打印,但是日志的排版等还是没有特别直观,这里我们自定义来实现sql的打印格式。
本篇文章的内容主要是将原本打印格式中分开显示的 ? 和 参数列表整合到SQL中,方便我们在进行错误追踪时省去填入参数,提高效率

创建SQL拦截器

package com.pig4cloud.pig.common.mybatis.config;import com.baomidou.mybatisplus.core.enums.IEnum;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.*;/*** @author chenxh* @date 2021/3/31*/
@Slf4j
@Intercepts({@Signature(type = StatementHandler.class,method = "query",args = {Statement.class, ResultHandler.class}
), @Signature(type = StatementHandler.class,method = "update",args = {Statement.class}
), @Signature(type = StatementHandler.class,method = "batch",args = {Statement.class}
)})
public class MybatisSqlInterceptor extends AbstractSqlParserHandler implements Interceptor {/*** 获取配置中需要拦截的表,自定义配置,逗号隔开*/@Value("#{'${tmall.sync.tables:}'.split(',')}")private List<String> tableNames;/*** 忽略插入sql_log表的语句*/private static final String IGNORE_SQL_PREFIX = "insert into sql_log";@Overridepublic Object intercept(Invocation invocation) throws Throwable {if (CollectionUtils.isEmpty(tableNames)) {return invocation.proceed();}StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());MetaObject metaObject = SystemMetaObject.forObject(statementHandler);MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");String sql = boundSql.getSql().replaceAll("\\s+", " ").toLowerCase();if (sql.toLowerCase(Locale.ENGLISH).startsWith(IGNORE_SQL_PREFIX)) {return invocation.proceed();}List<ParameterMapping> parameterMappings = new ArrayList<>(boundSql.getParameterMappings());Object parameterObject = boundSql.getParameterObject();if (parameterMappings.isEmpty() && parameterObject == null) {log.warn("parameterMappings is empty or parameterObject is null");return invocation.proceed();}Configuration configuration = mappedStatement.getConfiguration();TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();try {this.sqlParser(metaObject);String parameter = "null";MetaObject newMetaObject = configuration.newMetaObject(parameterObject);for (ParameterMapping parameterMapping : parameterMappings) {if (parameterMapping.getMode() == ParameterMode.OUT) {continue;}String propertyName = parameterMapping.getProperty();if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {parameter = getParameterValue(parameterObject);} else if (newMetaObject.hasGetter(propertyName)) {parameter = getParameterValue(newMetaObject.getValue(propertyName));} else if (boundSql.hasAdditionalParameter(propertyName)) {parameter = getParameterValue(boundSql.getAdditionalParameter(propertyName));}sql = sql.replaceFirst("\\?", parameter);}log.info("===========EXECUTE SQL===========");log.info("------> "+ sql);log.info("===========EXECUTE END===========");// 将拦截到的sql语句插入日志表中} catch (Exception e) {log.error(String.format("intercept sql error: [%s]", sql), e);}return invocation.proceed();}/*** 获取参数** @param param Object类型参数* @return 转换之后的参数*/private static String getParameterValue(Object param) {if (param == null) {return "null";}if (param instanceof Number) {return param.toString();}String value = null;if (param instanceof String) {value = param.toString();} else if (param instanceof Date) {new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) param);} else if (param instanceof IEnum) {value = String.valueOf(((IEnum) param).getValue());} else {value = param.toString();}return StringUtils.quotaMark(value);}@Overridepublic Object plugin(Object o) {if (o instanceof StatementHandler) {return Plugin.wrap(o, this);}return o;}@Overridepublic void setProperties(Properties properties) {}}

进行注入,交由spring来统一管理

@Configuration(proxyBeanMethods = false)
public class MybatisAutoConfiguration implements WebMvcConfigurer {/*** 自定义sql打印格式* @return*/@Beanpublic MybatisSqlInterceptor performanceInterceptor() {return new MybatisSqlInterceptor();}
}

只需要如上两个步骤即可,代码可以直接使用,我就便可以实现SQL的自定义格式,在这里我将sql的参数直接替换到了sql语句中,这样更方便我们日常查看以及debug的使用。

以下便是sql:

到这里,感谢您的浏览,如果您发现有需要更改之处,还恳请您能够指出来,再次感谢!

MybatisPlus自定义SQL日志打印相关推荐

  1. mybatis-plus 开启与关闭 SQL 日志打印

    开启打印 Mybatis-plus 需要通过下面的方式开启控制台 SQL 日志打印 mybatis-plus:configuration:log-impl: org.apache.ibatis.log ...

  2. Mybatis-plus开启或者关闭SQL日志打印

    Mybatis-plus开启或者关闭SQL日志打印 在application.yml中配置,开启或者关闭sql日志打印: 更改log-impl项即可.NoLoggingImpl不打印日志,StdOut ...

  3. SpringBoot集成MyBatis-Plus自定义SQL

    1.说明 本文介绍Spring Boot集成MyBatis-Plus框架后, 基于已经创建好的Spring Boot工程, 添加自定义的SQL实现复杂查询等操作. 自定义SQL主要有两种方式, 一种是 ...

  4. mybatis-plus自定义sql报错 ew.customSqlSegment

    mybatis-plus自定义sql报错: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibat ...

  5. MybatisPlus:SQL语句打印、SQL分析、自定义主键值策略填充(IdType.INPUT)、动态表名、多租户、枚举、类型处理器、连表自定义SQL(使用wrapper)

    文章目录 1. 简单使用以及配置 - 带分页配置 2. 用法 2.0 Wrapper属性 2.1 @TableId - 自定义主键生成策略 2.2 @TableField - 自定义字段值填充 2.3 ...

  6. Mybatis-plus开启和关闭SQL日志打印

    开启日志打印 application.yml文件开启方式: mybatis-plus:mapper-locations: classpath:mapper/*.xmlconfiguration:#关闭 ...

  7. SpringBoot开启mybatis-plus控制台SQL日志

    1.在yml文档中添加如下配置即可 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 2 ...

  8. MybatisPlus自定义 Sql 实现多表查询

    目录 概述 编写代码 案例流程说明 控制层 服务层 数据访问层 自定义 SQL 测试 MybatiPlus文档 概述 MyBatis-Plus (opens new window)(简称 MP)是一个 ...

  9. Springboot mybatis 配置sql日志打印

    1.方式一 ######################################################## ###配置打印sql ########################## ...

最新文章

  1. 宾阳 计算机 培训,宾阳县职业技术学校
  2. 【hibernate框架】核心开发接口-saveOrUpdate方法与delete方法
  3. 获得虚拟服务器相对路径,在web应用中获取相对路径和绝对路径
  4. angular核心原理解析3:指令的执行过程
  5. linux下载哪个python版本-Linux安装多个Python版本
  6. 汇编语言随笔(1)- 初步介绍和寄存器概览
  7. 本周学习总结(ng-zorro/MDN索引/读书笔记)
  8. Qt Creator部署到设备
  9. jquery.validation.js 使用
  10. 如何处理错误消息Unable to install breakpoint due to missing line number attributes
  11. BaseAudioContext
  12. 使用nvl就不能groupby了吗_现在的手机大部分都不能换电池,使用1至2年就需要更换吗?...
  13. C# OpenFileDialog 使用
  14. 分子动力学模拟算法框架
  15. 测试网速wifi软件,测网速工具 一键wifi测速
  16. 关于sublime text4 和Google Chrome 的live reload插件
  17. itext tif图片转为pdf
  18. 中文地址识别api的使用测试,快递地址自动补全,自动识别省市区,地址清洗,到底哪个好用?
  19. spring boot 访问路径404是会转到/error路径,倒是拦截器失效
  20. Python-str2int

热门文章

  1. Web前端布局实战:三国杀页面布局(上)
  2. 重磅!Apollo 5.0来了,百度变身「老司机」!
  3. VN服务器IP地址切换,客户端连接解决方案!
  4. oracle数据库scn是什么,深入了解ORACLE数据库的SCN
  5. 360极速浏览器国际版?
  6. 新代系统怎样看服务器ip,新代数控系统是如何进行网络连接
  7. Scapy的下载和安装(二)
  8. 内存管理(二) ARC
  9. Redis-Lua语言:简单小巧但功能强大
  10. 2k*2k 棋盘覆盖问题