MyBatis 原始碼篇 日誌模組2

2021-10-02 17:24:32 字數 2862 閱讀 5302

上一章的案例,配置日誌級別為 debug,執行乙個簡單的查詢操作,會將 jdbc 操作列印出來。本章通過 mybatis 日誌部分原始碼分析它是如何實現日誌列印的。

在 mybatis 的日誌模組中有乙個 jdbc package,package 中的內容如下圖所示:

basejdbclogger 是乙個抽象類,它是 jdbc package 下其他類的父類,類繼承關係如下圖所示:

basejdbclogger 類中定義了一些公共集合和簡單的工具方法,提供給子類使用。

basejdbclogger 的子類有如下特性:

mybatis 就是通過動態**的方式,對 jdbc 原生類進行了一層封裝,在**類的 invoke 方法中新增對應 jdbc 操作的日誌列印功能。

connectionlogger 的實現如下:

public

final

class connectionlogger extends basejdbclogger implements

invocationhandler

@override

public

object invoke(object proxy, method method, object params)

throws

throwable

//如果呼叫的是preparestatement()方法、preparecall()方法或createstatement()方法

//則在建立相應的statement物件後,為其建立**物件並返回該**物件

if ("preparestatement".equals(method.getname()))

//呼叫connection的preparestatement()方法,得到preparedstatement物件

preparedstatement stmt =(preparedstatement) method.invoke(connection, params);

//為preparedstatement物件建立**物件

stmt =preparedstatementlogger.newinstance(stmt, statementlog, querystack);

return

stmt;

} else

if ("preparecall".equals(method.getname()))

preparedstatement stmt =(preparedstatement) method.invoke(connection, params);

stmt =preparedstatementlogger.newinstance(stmt, statementlog, querystack);

return

stmt;

} else

if ("createstatement".equals(method.getname()))

else

} catch

(throwable t)

} /** creates a logging version of a connection

** @param conn - the original connection

* @return - the connection with logging

*/public

static connection newinstance(connection conn, log statementlog, int

querystack) , handler);

} /* *

* @return the connection

*/public

connection getconnection()

}

其他子類的實現與 connectionlogger 類似,不在贅述。

connectionlogger 會建立 preparedstatementlogger 或 statementlogger,preparedstatementlogger 會建立 resultsetlogger,這樣就保證了每一步 jdbc 操作在 debug 日誌級別下都有日誌輸出。

那麼 connectionlogger 又是在**建立的呢?跟蹤 sql 的執行流程,在 org.apache.ibatis.executor.baseexecutor#getconnection 方法中找到 connectionlogger 的建立**:

protected connection getconnection(log statementlog) throws

sqlexception

else

}

從原始碼中可以看出,如果日誌級別為 debug,則會建立**類 connectionlogger,否則只會使用正常的 connection 物件。

mybatis 原始碼篇

mybatis 原始碼篇-整體架構

mybatis 原始碼篇-sql 執行的流程

mybatis 原始碼篇-資源載入

mybatis 原始碼篇-日誌模組1

mybatis 原始碼篇-日誌模組2

mybatis 原始碼篇-外掛程式模組

mybatis 原始碼篇-datasource

mybatis 原始碼篇-transaction

mybatis 原始碼篇-mybatis-spring 剖析

Mybatis原始碼解析 日誌

mybatis自己有一套統一的日誌介面供上層使用,使用介面卡模式為常用日誌框架提供了介面卡 負責建立對應日誌元件的介面卡,其靜態塊初始化載入會按順序載入各日誌元件的介面卡,並使用第乙個載入到的日誌元件介面卡,儲存到logconstructor這個靜態欄位裡 basejdbclogger記錄了繫結sq...

Mybatis日誌原始碼分析

在使用mybatis的時候,可以看到控制台的日誌輸出。有很多的日誌框架,那麼mybatis如何與這些日誌框架進行整合呢?優先順序又如何確定?日誌資訊如何優雅的輸出?使用介面進行標準統一。public inte ce log每個日誌的實現都提供對應的介面卡,以log4j為例 將第三方的日誌介面轉換為m...

mybatis之日誌原始碼解析

mybatis日誌這塊運用的設計模式有點像slf4j類似一樣,運用了構造器 介面卡和外觀者設計模式。應用嘗試載入各個日誌框架類來封裝成內部自己設計的log介面。這整個過程比較簡單,大概流程如下 原始碼實現流程 第一步,通過org.apache.ibatis.logging.logfactory類初始...