我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Mybatis拦截器打印sql问题怎么解决

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Mybatis拦截器打印sql问题怎么解决

本篇内容介绍了“Mybatis拦截器打印sql问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    1.log4j2配置修改

    关闭log4j2打印mybatis的sql配置,如果本来就没开启,那不需要。

    Mybatis拦截器打印sql问题怎么解决

    2.配置日志开关

    在springboot的yml文件配置变量logging.sql.enable=true,对拦截器做开关控制。

    Mybatis拦截器打印sql问题怎么解决

    3.添加拦截器插件

    // 采用自定义拦截器打印sql日志sessionFactory.setPlugins(new Interceptor[]{this.getSqlLogInterceptor()});

    Mybatis拦截器打印sql问题怎么解决

    4.拦截器逻辑描述

    4.1 注入开关

     @Value("${logging.sql.enable:true}") private Boolean sqlEnable;

    4.2 获取sql

    Object target = invocation.getTarget();StatementHandler statementHandler = (StatementHandler) target; //获取绑定的SQL对象BoundSql boundSql = statementHandler.getBoundSql(); //得到需要执行的sql语句,并进行格式String sql = boundSql.getSql();

    4.2 获取参数

    //需要绑定的参数映射对象List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();

    4.3 sql替换参数

    public String buidSql(String sql,Object[] parameters) {        if (parameters == null || sql == null) {            return "";        }        List<Object> parametersArray = Arrays.asList(parameters);        List<Object> list = new ArrayList<Object>(parametersArray);        while (sql.indexOf("?") != -1 && list.size() > 0 && parameters.length > 0) {            Object obj = list.get(0);            if(null!=obj && obj instanceof String){                sql = sql.replaceFirst("\\?", "'"+obj.toString()+"'");            }else if(null!=obj){                sql = sql.replaceFirst("\\?", obj.toString());            }             list.remove(0);        }        return sql.replaceAll("(\r?\n(\\s*\r?\n)+)", "\r\n");    }

    4.4 打印sql

    log.debug(String.format(                        "\n###########################   Sql Start  ###########################" +                                "\n StartTime  :  %s" +                                "\n ExecuteID  :  %s" +                                "\n ExecuteSQL  :  %s" +                                "\n ExecuteTime  :  %s ms" +                                "\n###########################   Sql End  ###########################\n"                         ,startTimeStr,executeID,this.buidSql(sql,args.toString().split(",")),exeTime));

    4.5打印效果

    Mybatis拦截器打印sql问题怎么解决

    拦截器完整代码

    package com.cloudpaas.plugin.mybatis.interceptor; 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.scripting.defaults.DefaultParameterHandler;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 java.lang.reflect.Field;import java.sql.Statement;import java.text.SimpleDateFormat;import java.util.*; @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 })})@Slf4jpublic class SqlLogInterceptor implements Interceptor {    private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");     @Value("${logging.sql.enable:true}")    private Boolean sqlEnable;     @Override    public Object intercept(Invocation invocation) throws Throwable {        if(!sqlEnable){            return invocation.proceed();        }        Object target = invocation.getTarget();        MetaObject mObject = SystemMetaObject.forObject(invocation.getTarget());        MappedStatement mappedStatement = (MappedStatement)mObject.getValue("delegate.mappedStatement");        // 执行的mapper statement ID        String executeID = mappedStatement.getId();        //获取当前的开始时间戳        long startTime = System.currentTimeMillis();        //记录当前时间        String startTimeStr=sdf.format(new Date());        StatementHandler statementHandler = (StatementHandler) target;        try {            return invocation.proceed();        } finally {            long endTime = System.currentTimeMillis();            //sql的执行的时间            long exeTime = endTime - startTime;            try{                //获取绑定的SQL对象                BoundSql boundSql = statementHandler.getBoundSql();                //得到需要执行的sql语句,并进行格式                String sql = boundSql.getSql();                sql=formatSql(sql);                //得到默认的参数处理器                DefaultParameterHandler dph=(DefaultParameterHandler)statementHandler.getParameterHandler();                //利用反射机制,从DefaultParameterHandler获取Configuration和TypeHandlerRegistry                Field configurationField=dph.getClass().getDeclaredField("configuration");                Field typeHandlerRegistryField=dph.getClass().getDeclaredField("typeHandlerRegistry");                //设置私有属性可访问                configurationField.setAccessible(true);                //设置私有属性可访问                typeHandlerRegistryField.setAccessible(true);                Configuration configuration=(Configuration) configurationField.get(dph);                TypeHandlerRegistry typeHandlerRegistry=(TypeHandlerRegistry) typeHandlerRegistryField.get(dph);                //sql的参数对象                Object parameterObject = boundSql.getParameterObject();                //需要绑定的参数映射对象                List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();                //处理sql的参数,该部分参考的是DefaultParameterHandler中setParameters方法中的实现                StringBuffer args=new StringBuffer();                if(parameterMappingList!=null && parameterMappingList.size()>0){                    for(ParameterMapping parameterMapping:parameterMappingList){                        //如果该参数不是输出参数,则进行处理                        if (parameterMapping.getMode() != ParameterMode.OUT) {                            Object value;                            //参数的名字,属性                            String propertyName = parameterMapping.getProperty();                            //先从附加的,主要是list、array等的处理                            if (boundSql.hasAdditionalParameter(propertyName)) {                                value = boundSql.getAdditionalParameter(propertyName);                            } else if (parameterObject == null) {                                value = null;                            } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {                                //typeHandlerRegistry注册了某个类的处理                                value = parameterObject;                            } else {                                //默认的MetaObject 的处理,根据参数获取值                                MetaObject metaObject = configuration.newMetaObject(parameterObject);                                value = metaObject.getValue(propertyName);                            }                            if(value!=null){                                if(value instanceof Date){                                    //如果是日期,则格式化一下                                    value=sdf.format(value);                                }                            }                            args.append(",").append(value);                        }                    }                    //删除第一个逗号                    args.deleteCharAt(0);                }                log.debug(String.format(                        "\n###########################   Sql Start  ###########################" +                                "\n StartTime  :  %s" +                                "\n ExecuteID  :  %s" +                                "\n ExecuteSQL  :  %s" +                                "\n ExecuteTime  :  %s ms" +                                "\n###########################   Sql End  ###########################\n"                         ,startTimeStr,executeID,this.buidSql(sql,args.toString().split(",")),exeTime));            }catch(Exception e){            }        }    }     @Override    public Object plugin(Object target) {        return Plugin.wrap(target, this);    }     @Override    public void setProperties(Properties properties) {     }     private String formatSql(String sql) {        // 输入sql字符串空判断        if (sql == null || sql.length() == 0) {            return "";        }        //格式sql 将回车换行制表符等替换成空,在将连续多个空格替换成1个空格,然后在去掉左右括号两边的空格,在去掉逗号左右两个的空格        return sql.replaceAll("[\\t\\n\\x0B\\f\\r]", "").replaceAll(" +", " ")                .replaceAll(" *\\( *", "(").replaceAll(" *\\) *", ")").replaceAll(" *, *", ",");     }     public String buidSql(String sql,Object[] parameters) {        if (parameters == null || sql == null) {            return "";        }        List<Object> parametersArray = Arrays.asList(parameters);        List<Object> list = new ArrayList<Object>(parametersArray);        while (sql.indexOf("?") != -1 && list.size() > 0 && parameters.length > 0) {            Object obj = list.get(0);            if(null!=obj && obj instanceof String){                sql = sql.replaceFirst("\\?", "'"+obj.toString()+"'");            }else if(null!=obj){                sql = sql.replaceFirst("\\?", obj.toString());            }             list.remove(0);        }        return sql.replaceAll("(\r?\n(\\s*\r?\n)+)", "\r\n");    }}

    “Mybatis拦截器打印sql问题怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Mybatis拦截器打印sql问题怎么解决

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Mybatis拦截器打印sql问题怎么解决

    本篇内容介绍了“Mybatis拦截器打印sql问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.log4j2配置修改关闭log4
    2023-07-05

    Mybatis拦截器打印sql问题

    这篇文章主要介绍了Mybatis拦截器打印sql问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-13

    mybatis-plus的sql语句打印问题怎么解决

    本篇内容介绍了“mybatis-plus的sql语句打印问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!第一种方式:mybatis
    2023-06-30

    SpringBoot怎么打印mybatis的执行sql问题

    这篇文章主要介绍了SpringBoot怎么打印mybatis的执行sql问题的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot怎么打印mybatis的执行sql问题文章都会有所收获,下面我们一起
    2023-07-05

    springboot拦截返回数据问题怎么解决

    在Spring Boot中,可以使用拦截器来拦截返回数据,并对返回数据进行处理。可以按照以下步骤来解决该问题:1. 创建一个实现了`ResponseBodyAdvice`接口的拦截器类,用来拦截返回数据并进行处理。该接口包含了三个方法,分别
    2023-10-12

    mybatis拦截器无法注入spring bean怎么解决

    这篇文章主要介绍“mybatis拦截器无法注入spring bean怎么解决”,在日常操作中,相信很多人在mybatis拦截器无法注入spring bean怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
    2023-06-29

    MyBatis中怎么实现自定义的SQL拦截器

    在 MyBatis 中实现自定义的 SQL 拦截器,通常可以通过实现 org.apache.ibatis.plugin.Interceptor 接口来实现。下面是一个简单的示例:创建一个自定义的拦截器类,实现 Interceptor 接口:
    MyBatis中怎么实现自定义的SQL拦截器
    2024-05-08

    Struts2拦截器 关于解决登录的问题

    拦截器的工作原理如图 拦截器是由每一个action请求(request)都包装在一系列的拦截器的内部,通过redirectAction再一次发送请求。拦截器可以在Action执行直线做相似的操作也可以在Action执行直后做回收操作。我们可
    2023-05-31

    SpringBoot拦截器返回false显示跨域问题怎么解决

    本文小编为大家详细介绍“SpringBoot拦截器返回false显示跨域问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot拦截器返回false显示跨域问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢
    2023-06-30

    Mybatis的sql注释问题怎么解决

    这篇文章主要介绍“Mybatis的sql注释问题怎么解决”,在日常操作中,相信很多人在Mybatis的sql注释问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Mybatis的sql注释问题怎么解决
    2023-07-02

    SpringBoot security默认拦截静态资源问题怎么解决

    这篇文章主要讲解了“SpringBoot security默认拦截静态资源问题怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot security默认拦截静态资源问题
    2023-07-05

    mybatis中的动态sql问题怎么解决

    本篇内容主要讲解“mybatis中的动态sql问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mybatis中的动态sql问题怎么解决”吧!Mybatis框架的动态SQL技术是一种根据
    2023-07-05

    Windows11网络打印机问题怎么解决

    这篇“Windows11网络打印机问题怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Windows11网络打印机问题
    2023-04-14

    window.open()被浏览器拦截怎么解决

    本篇内容介绍了“window.open()被浏览器拦截怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、问题描述以下是浏览器拦截示例
    2023-07-02

    怎么在Python中通过设置Cookie解决网站拦截问题

    本篇文章为大家展示了怎么在Python中通过设置Cookie解决网站拦截问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性
    2023-06-06

    vuecli3打包后前端配置拦截器无效怎么解决

    这篇“vuecli3打包后前端配置拦截器无效怎么解决”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vuecli3打包后前端配
    2023-06-30

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录