mybatis怎麼打印出sql,我被誤導了很多年

關於mybatis怎麼打印出sql這個問題,可以百度一下,很多答案都有類似這樣的答案:

mybatis怎麼打印出sql,我被誤導了很多年

就是把java.sql.*,com.ibatis等的日誌級別都配置成debug的,也許這麼配置與默認的info配置相比真的有效果,把sql打印出來了。可是我今天才發現,打印sql與這些java.sql,com.ibatis包半毛錢關係都沒有。至少我調試的mybatis-3.3.0.jar就是這樣的,因為它打印日誌的對象是org.apache.ibatis.logging.slf4j.Slf4jImpl(statementLog),而statementLog又是在系統啟動時,掃描的logId(如com.**.Mapper.query)作為其構造參數的。是否打印日誌就是這個參數是否與log4j.xml,與log4j.properties裡的log4j.logger匹配來決定的。下面通過源碼來分析整個過程:

1.statementLog是否為debug,來決定是否打印sql

代碼:org.apache.ibatis.executor.SimpleExecutor

mybatis怎麼打印出sql,我被誤導了很多年

如果進入上圖裡創建ConnectionLogger對象的代碼,就可執行真正打印日誌的代碼。如下圖

類:org.apache.ibatis.logging.jdbc.BaseJdbcLogger

代碼行:ConnectionLogger(BaseJdbcLogger).debug(String, boolean) line: 141

mybatis怎麼打印出sql,我被誤導了很多年

2.statementLog的注入

statementLog來源於MappendStatement

mybatis怎麼打印出sql,我被誤導了很多年

而MappendStatement是org.apache.ibatis.session.Configuration註冊進去的。

mybatis怎麼打印出sql,我被誤導了很多年

再看MappendStatement的構造過程是如何創建Log的。

類:org.apache.ibatis.mapping.MappedStatement.Builder

mybatis怎麼打印出sql,我被誤導了很多年

LogFactory.getLog(xx)這行代碼再熟悉不過了吧,從這裡的值來看,是不是跟什麼java.sql、com.ibatis沒有半毛錢關係。

mybatis用的日誌框架確實足夠強大,無論我們是用slf4j還是common-logger,它都能用起來,這是什麼麼呢?

看下類:org.apache.ibatis.logging.LogFactory:

mybatis怎麼打印出sql,我被誤導了很多年

在加載這個類時會執行上面的靜態代碼塊,這裡會依次去嘗試各種日誌框架的實現。嘗試代碼如下:

mybatis怎麼打印出sql,我被誤導了很多年

如果有一個成功,則logConstructor就被實例化,不為空了,後面的就沒有機會執行了。從這裡的代碼我又學了一招,怎麼兼容客戶端不同的jar實現,即使客戶端沒有其中的一個實現jar包,代碼也不會錯。

最後還是回答一下標題,如何打印sql呢,比如我上面的代碼就配置一下log4j.logger.com.helijia.search=DEBUG,就可以了。


分享到:


相關文章: