(转)logback 打印Mybitis中的sql执行过程

Posted 滤v镜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(转)logback 打印Mybitis中的sql执行过程相关的知识,希望对你有一定的参考价值。

场景:在程序开发过程中经常需要跟踪程序中sql语句的执行过程,在控制台打印出sql语句和对应的参数传递就能够更快的定位错误!

原文出处:http://www.cnblogs.com/beiyeren/p/4196134.html

这里所采用的日志框架为logback

 

1 不同版本的Mybitis对应不同的控制策略

1.1 myBatis3.0.6左右的版本时

打印sql的时候只需要配置如下属性:

<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG" />
<logger name="java.sql.PreparedStatement" level="DEBUG" />

源码解析:

PreparedStatementLogger里面看这个log.isDebugEnabled()
 
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
    try {
      if (EXECUTE_METHODS.contains(method.getName())) {
        if (log.isDebugEnabled()) {
          log.debug("==>  Executing: " + removeBreakingWhitespace(sql));
          log.debug("==> Parameters: " + getParameterValueString());
        }
        clearColumnInfo();
        if ("executeQuery".equals(method.getName())) {
          ResultSet rs = (ResultSet) method.invoke(statement, params);
          if (rs != null) {
            return ResultSetLogger.newInstance(rs);
          } else {
            return null;
          }
        } else {
          return method.invoke(statement, params);
        }
      }
 

这个log定义的是PreparedStatement

private static final Log log = LogFactory.getLog(PreparedStatement.class);

 

1.2 在myBatis3.2.7左右版本(以上也可以)

只需要简单的两步即可!

更改了打印Sql的模式,它将sql打印细化到了每一个mapperStatement的每一个方法上。

如果你打算有一个全局配置打印所有的sql,则需要如下配置

在mybatis的configuration中增加setting配置

<settings>
        <setting name="logPrefix" value="dao."/>
</settings>

 然后增加配置

<logger name="dao" level="DEBUG"/>

源码解析:

ConnectionLogger
 
public Object invoke(Object proxy, Method method, Object[] params)
      throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, params);
      }    
      if ("prepareStatement".equals(method.getName())) {
        if (isDebugEnabled()) {
          debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
        }        
        PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
        stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack);
        return stmt;
      }
 

其中的isDebugEnabled()指的是

protected boolean isDebugEnabled() {
    return statementLog.isDebugEnabled();
}

注意这里的statementLog,看SimpleExecutor的prepareStatement(handler, ms.getStatementLog());

 
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
    Statement stmt = null;
    try {
      Configuration configuration = ms.getConfiguration();
      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.<E>query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
  }
 

这个statementLog是ms.getStatementLog()而来的。而MappedStatement的StatementLog

String logId = id;
 if (configuration.getLogPrefix() != null) logId = configuration.getLogPrefix() + id;
 mappedStatement.statementLog = LogFactory.getLog(logId);

这里可以看到,logPrefix决定了所有log前缀,所以只需要配置logPrefix就行了

 

以上是关于(转)logback 打印Mybitis中的sql执行过程的主要内容,如果未能解决你的问题,请参考以下文章

springboot中logback打印日志(转)

logback打印sql

9springcloud整合logback打印sql语句

logback mybatis 打印sql语句

logback.xml引入外部配置文件

pringBoot结合LogBack打印Sql