1. 程式人生 > >使用MyBatis和logBack時在日誌中輸出sql

使用MyBatis和logBack時在日誌中輸出sql

測試環境:MyBatis3.2.7+logBack1.1.3

1. 在MyBatis的配置檔案中增加setting配置
注意:dao.中的字元“.”是必須的

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

2.在logBack的配置檔案中增加logger配置

<logger name="dao" level="DEBUG">
	<!--daoFILE為實際定義的appender-->
	<appender-ref ref="daoFILE" />
</logger>

3.原始碼解析
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就行了

參考資料: