前言

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. MySQL5.7 支持一个表有多个INSERT/DELETE/UPDATE触发器
  2. 用户线程和内核线程之间的区别
  3. 不是每个人都可以坚持!
  4. [转载]用UglifyJS2合并压缩混淆JS代码——javascript系列
  5. 异步生成器_使用生成器实现异步并等待
  6. boost signal2 trackable
  7. Git笔记(34) 调试
  8. leetcode5086:smallest-subsequence-of-distinct-characters
  9. python为什么叫爬虫-python为什么叫爬虫?为什么python开发会突然火起来?
  10. [转载][工具]Eclipse Console 加大显示的行数,禁止弹出
  11. Zookeeper学习笔记——1 单机版本环境搭建
  12. oracle国家字符集
  13. 【Ngrok】小米球实践-内网穿透【映射本地到外网访问】
  14. H5和小程序区别详解
  15. windows网络和共享中心“查看基本网络信息并设置连接”为“未知”的解决方案...
  16. 【win7安装composer错误】:The quot;https://getcomposer.org/download/1.6.2/composer.phar.sigquot; file cou
  17. Gos ——内存管理系统
  18. 10000marker_为什么跑全基因组dna时为什么用10000bp的marker
  19. RecycleView刷新 齿轮转动动画效果
  20. 反游戏规则~触发5亿创设~引发3-6个跌停?

热门文章

  1. Arduino ESP8266 MQTT 阿里 腾讯 连接示例
  2. GPT转MBR怎么转?
  3. 让你的文章变得‘好看’--分享一些不错的字体颜色
  4. UDS - 10.2 DiagnosticSessionControl (10) service
  5. c#连mysql 连接字符串
  6. cygwin mysql安装教程_Cygwin 下安装Python MySQLdb
  7. 药品管理系统设计文档
  8. 如何听节拍器_怎么听节拍器视频
  9. PPT课件免费下载!国家精品公开课:《Python编程入门》
  10. Camtasia Studio 2021软件免费秘钥序列号下载录制视频或微课教程