zoukankan      html  css  js  c++  java
  • log4j打印mybatis执行sql,将占位符换成真实的参数输出

    背景:

    在我日常码代码的时候,由于对mybatis的动态sql,比较依赖,并且有时候需求复杂,导致sql较长,而且参数众多,当出现问题是,需要将sql,放到navicat里面去执行查看结果,但是对于复杂的sql来说,众多的参数,一个一个替换。当真很麻烦,于是萌生出可不可以将sql直接输出,不在出线sql和参数分开的情况,可以减少很多麻烦,在我找度娘,一次又一次的尝试,我还是没有发现,在log4j的配置文件里面。有这个功能,所以最后萌生出改写源码的想法,之后我也会尝试继续寻找,有没有官方的API提供,本文讲述我自己改写源代码实现的方案
    一、针对DEMO搭建SSM项目(略)
    二、采用的log4j的版本(这里由于log的众多实现,有可能出线log4j的冲突,而且我也没有滤的特别清楚,所以贴出自己使用的log4j的版本,采用maven提供)
    [html] view plain copy
     
    1. <span style="white-space:pre;">         </span><!-- log4j 日志 -->  
    2.             <dependency>  
    3.                 <groupId>log4j</groupId>  
    4.                 <artifactId>log4j</artifactId>  
    5.                 <version>${log4j-version}</version>  
    6.             </dependency>  


    三、首先实现输出mybatis输出sql
    1、引入jar包(同上)
    2、配置mybatis输出sql的配置项
    [html] view plain copy
     
    1. <span style="white-space:pre;"</span><settings>  
    2.         <setting name="logImpl" value="LOG4J" />  
    3.     </settings>  
    3、添加logj4j.properties文件
    [plain] view plain copy
     
    1. #logFile  
    2. log4j.rootLogger=DEBUG,Console  
    3. #Console      
    4. log4j.appender.Console=org.apache.log4j.ConsoleAppender    
    5. log4j.appender.console.Threshold=INFO  
    6. log4j.appender.console.ImmediateFlush=true  
    7. log4j.appender.Console.Target=System.out  
    8. log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
    9. log4j.appender.Console.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss}[%t] %l: %x%m%n  
    10.   
    11. # 日志文件(logFile)  
    12. log4j.appender.logFile=org.apache.log4j.FileAppender  
    13. log4j.appender.logFile.Threshold=DEBUG  
    14. # 立即输出  
    15. #log4j.appender.logFile.ImmediateFlush=true   
    16. #log4j.appender.logFile.Append=true  
    17. #log4j.appender.logFile.File=D:/logs/log.log4j  
    18. #log4j.appender.logFile.layout=org.apache.log4j.PatternLayout  
    19. #log4j.appender.logFile.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss}[%t] %l: %x%m%n  
    20.   
    21. log4j.logger.org.apache=ERROR  
    22. log4j.logger.org.mybatis=ERROR    
    23. log4j.logger.org.springframework=ERROR    
    24. #这个需要   
    25. log4j.logger.log4jdbc.debug=ERROR    
    26.   
    27. log4j.logger.jdbc.audit=ERROR  
    28. log4j.logger.jdbc.resultset=ERROR    
    29. #这个打印SQL语句非常重要    
    30. log4j.logger.jdbc.sqlonly=DEBUG  
    31. log4j.logger.jdbc.sqltiming=ERROR   
    32. log4j.logger.jdbc.connection=FATAL  
    4、测试结果
    [plain] view plain copy
     
    1. ==>  Preparing: select u.id as id ,u.name as name , u.pwd as pwd from user u where u.pwd = ? and u.id = ?;   
    2. ==> Parameters: 123(String), 1(String)  
    3. <==      Total: 0  
    显然:参数和sql是分离的,现在要实现将参数嵌套进sql中,实现上面的想法
     
    通过源码的分析最后我决定动(org.apache.ibatis.logging.jdbc.BaseJdbcLogger)这个类,它的作用是输出最后的sql
     
    方法步骤:
     
    1、找到这个类的全路径,找到源码
    2、在src下创建一个同路径下的BaseJdbcLogger类,并且将源码原封不动的贴近刚创建的类,
    3、找到需要修改的方法,我贴一下我准备修改的方法
    [java] view plain copy
     
    1. protected void debug(String text, boolean input) {  
    2.    if (statementLog.isDebugEnabled()) {  
    3.      statementLog.debug(prefix(input) + text);  
    4.    }  
    5.  }  
    目前的这个是BaseJdbcLogger.debug的源码,其中(text:是需要打印的文本,input:表示前面的“==>”的方向)
    经过我的修改:
    [java] view plain copy
     
    1. /* 打印的sql */  
    2. private static String sql = "";  
    3. protected void debug(String text, boolean input) {  
    4.     text = text.trim();  
    5.     if (statementLog.isDebugEnabled()) {  
    6.     if(text.startsWith("Preparing:")){  
    7.       sql = text.substring(text.indexOf(":")+1);  
    8.       return ;  
    9.     }  
    10.     if(text.startsWith("Parameters:")){  
    11.       String temp = text.substring(text.indexOf(":")+1);  
    12.       String[] split = temp.split(",");  
    13.       if(split != null & split.length > 0){  
    14.           for (String string2 : split) {  
    15.         String s = string2.trim();  
    16.         sql = sql.replaceFirst("\?", s.substring(0, s.indexOf("(")));  
    17.     }  
    18.       }  
    19.       text = "Preparing:"+ sql ;  
    20.       sql = "";  
    21.     }  
    22.     statementLog.debug(prefix(input) + text);  
    23.   }  
    24. }  
    最终输出结果:
    [plain] view plain copy
     
    1. ==> Preparing: select u.id as id ,u.name as name , u.pwd as pwd from user u where u.pwd = 123 and u.id = 1;  
    2. <== Total: 0  
    到到最终目的
    (虽然不是最好的方法,mybatis应该分装相应的配置,但是我没有发现,如果有码友发现了,请告知我,谢谢)
  • 相关阅读:
    Saltstack module gem 详解
    Saltstack module freezer 详解
    Saltstack module firewalld 详解
    Saltstack module file 详解
    Saltstack module event 详解
    Saltstack module etcd 详解
    Saltstack module environ 详解
    Saltstack module drbd 详解
    Saltstack module dnsutil 详解
    获取主页_剥离百度
  • 原文地址:https://www.cnblogs.com/swugogo/p/9000963.html
Copyright © 2011-2022 走看看