天天看點

Mybatis源碼分析02-整體架構和SessionFactory

更多精彩内容請關注

  • 微信公衆号:LifeSmile
  • 個人網站:www.lifesmile.cn

1.整體架構圖

Mybatis源碼分析02-整體架構和SessionFactory

1.1.接口層

接口層是MyBatis提供給開發人員的一套API.主要使用SqlSession接口.通過SqlSession接口和Mapper接口.開發人員,可以通知MyBatis架構調用那一條SQL指令以及SQL指令關聯參數.

1.2.資料處理層

資料處理層是MyBatis架構内部實作.來完成對資料庫具體操作.主要負責:

(1) 參數與SQL指令綁定

(2) SQL指令發送方式

(3) 查詢結果類型轉換

1.3.支撐層

支撐層用來完成MyBaits與資料庫基本連接配接方式以及SQL指令與配置檔案對應.主要負責:

(1) MyBatis與資料庫連接配接方式管理

(2) MyBatis對事務管理方式

(3) SQL指令與XML配置對應

(4) MyBatis查詢緩存管理

2.Mybatis調用流程

Mybatis源碼分析02-整體架構和SessionFactory

2.1.SqlSession:

接收開發人員提供Statement Id 和參數.并傳回操作結果

2.2.Executor:

MyBatis執行器,是MyBatis 排程的核心,負責SQL語句的生成和查詢緩存的維護

2.3.StatementHandler:

封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設定參數、将Statement結果集轉換成List集合。

2.4.ParameterHandler:

負責對使用者傳遞的參數轉換成JDBC Statement 所需要的參數

2.5.ResultSetHandler:

負責将JDBC傳回的ResultSet結果集對象轉換成List類型的集合

2.6.TypeHandler:

負責java資料類型和jdbc資料類型之間的映射和轉換

2.7.MappedStatement:

維護了一條<select|update|delete|insert>節點的封裝

2.7.8 SqlSource:

負責根據使用者傳遞的parameterObject,動态地生成SQL語句,将資訊封裝到BoundSql對象中,并傳回BoundSql表示動态生成的SQL語句以及相應的參數資訊

2.7.9 Configuration:

MyBatis所有的配置資訊都維持在Configuration對象之中

3.MyBatis架構使用方式

  • 基于XML配置檔案: SQL指令聲明在XML配置檔案中
  • 基于注解方式:SQL指令聲明在注解中

4.SessionFactory

點進源碼

public interface SqlSessionFactory {

  SqlSession openSession();

  SqlSession openSession(boolean autoCommit);
  SqlSession openSession(Connection connection);
  SqlSession openSession(TransactionIsolationLevel level);

  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);

  Configuration getConfiguration();

}
           

SqlSessionFactory是一個接口,他有2個實作DefaultSqlSessionFactory和SqlSessionManager(被抛棄).

4.1下面看SqlSessionFactory的建立:

// 指定全局配置檔案
        String resource = "mybatis-config.xml";
        // 讀取配置檔案
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 建構sqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
           
  1. 擷取配置檔案流
  2. 調用 SqlSessionFactoryBuilder對象的build(inputStream)方法;
  3. SqlSessionFactoryBuilder會根據輸入流inputStream等資訊建立XMLConfigBuilder對象
  4. SqlSessionFactoryBuilder 調用 XMLConfigBuilder對象的parse()方法;
  5. XMLConfigBuilder對象傳回Configuration對象;
  6. SqlSessionFactoryBuilder建立一個DefaultSessionFactory對象,并将Configuration對象作為參數傳給DefaultSessionFactory對象;
  7. SqlSessionFactoryBuilder 傳回 DefaultSessionFactory 對象給 Client ,供 Client使用。Client可以使用DefaultSessionFactory對象建立需要的SqlSession.

上述的初始化過程中,涉及到了以下幾個對象:

  • SqlSessionFactoryBuilder:SqlSessionFactory的構造器,用于建立SqlSessionFactory,采用了Builder設計模式
  • Configuration :該對象是mybatis-config.xml檔案中所有mybatis配置資訊
  • SqlSessionFactory:SqlSession工廠類,以工廠形式建立SqlSession對象,采用了Factory工廠設計模式
  • XmlConfigParser :負責将mybatis-config.xml配置檔案解析成Configuration對象,共SqlSessonFactoryBuilder使用,建立SqlSessionFactory

4.2.SqlSessionFactory涉及的設計模式----Builder(建造者模式)

Builder模式,稱為[建造者設計模式].使用多個簡單的對象一步一步建構一個複雜的對象.這種模式屬于[建立型模式].目前它是建立對象的最佳模式.

4.3.SqlSessionFactoryBuilder與SqlSessionFactory之間關系

SqlSessionFactoryBuilder是Builder模式中建造者,負責SqlSessionFactory對象的建立以及SqlSessionFactroy對象内部所需要内容的組裝.

5.configuration介紹

簡單的了解就是把配置檔案轉換為java對象.MyBatis架構支援開發人員通過配置檔案與其進行交流.在配置檔案所配置的資訊,在架構運作時,會被XMLConfigBuilder解析并存儲在一個Configuration對象中.Configuration對象會被作為參數傳送給DeFaultSqlSessionFactory.而DeFaultSqlSessionFactory根據Configuration對象資訊為Client建立對應特征的SqlSession對象.

private void parseConfiguration(XNode root) {
    try {
      propertiesElement(root.evalNode("properties")); //issue #117 read properties first
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      settingsElement(root.evalNode("settings"));
      environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
    
    ~~~