log4j打印mybatis执⾏sql,将占位符换成真实的参数输出
背景:
在我⽇常码代码的时候,由于对mybatis的动态sql,⽐较依赖,并且有时候需求复杂,导致sql较长,⽽且参数众多,当出现问题是,需要将sql,放到navicat⾥⾯去执⾏查看结果,但是对于复杂的sql来说,众多的参数,⼀个⼀个替换。当真很⿇烦,于是萌⽣出可不可以将sql直接输出,不在出线sql和参数分开的情况,可以减少很多⿇烦,在我度娘,⼀次⼜⼀次的尝试,我还是没有发现,在log4j的配置⽂件⾥⾯。有这个功能,所以最后萌⽣出改写源码的想法,之后我也会尝试继续寻,有没有官⽅的API提供,本⽂讲述我⾃⼰改写源代码实现的⽅案⼀、针对DEMO搭建SSM项⽬(略)
⼆、采⽤的log4j的版本(这⾥由于log的众多实现,有可能出线log4j的冲突,⽽且我也没有滤的特别清楚,所以贴出⾃⼰使⽤的log4j的版本,采⽤maven提供)
[html]
1. <span >        </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]
1. <span > </span><settings>
2.        <setting name="logImpl" value="LOG4J" />
3.    </settings>
3、添加logj4j.properties⽂件
[plain]
1. #logFile
2. Logger=DEBUG,Console
3. #Console
4. log4j.appender.Console=org.apache.log4j.ConsoleAppender
5. sole.Threshold=INFO
6. sole.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)log4j2 appender
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. apache=ERROR
22. batis=ERROR
23. springframework=ERROR
24. #这个需要
25. log4j.logger.log4jdbc.debug=ERROR
26.
27. log4j.logger.jdbc.audit=ERROR
28. log4j.sultset=ERROR
29. #这个打印SQL语句⾮常重要
30. log4j.logger.jdbc.sqlonly=DEBUG
31. log4j.logger.jdbc.sqltiming=ERROR
32. log4j.tion=FATAL
4、测试结果
[plain]
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]
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]
1. /* 打印的sql */
2. private static String sql = "";
3. protected void debug(String text, boolean input) {
4.    text = im();
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 = im();
16.        sql = placeFirst("\\?", s.substring(0, s.indexOf("(")));
17.    }
18.      }
19.      text = "Preparing:"+ sql ;
20.      sql = "";
21.    }
22.    statementLog.debug(prefix(input) + text);
23.  }
24. }
最终输出结果:
[plain]
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应该分装相应的配置,但是我没有发现,如果有码友发现了,请告知我,谢谢)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。