mybatis底層原理學習(一):SqlSessionFactory和SqlSession的建立過程

深夜程猿發表於2018-02-28

上篇文章和大家簡單入門了mybatis的增刪改查操作:寫給mybatis小白的入門指南。這篇文章就從原始碼角度分析一下mybatis的SqlSessionFactory的建立過程

SqlSessionFactory是SqlSession的建立工廠,每一個SqlSession例項代表應用程式和資料庫的一次連線。 在整個應用當中,我們應該只建立一個SqlSessionFactory例項,但是可以有多個SqlSession例項。那麼,SqlSessionFactory是怎麼建立出來的呢?下面我們看一張時序圖:

mybatis底層原理學習(一):SqlSessionFactory和SqlSession的建立過程

首先是讀取mybatis配置檔案到記憶體中,然後通過XMLConfigBuilder初始化基本配置,由SqlSessionFactoryBuilder來建立SqlSessionFactory,由SqlSessionFactory獲取SqlSession。
那麼,在建立SqlSessionFactory過程,mybatis具體做了什麼?我們在建立SqlSessionFactory的地方Debug進去(程式碼用的是上一篇文章的程式碼:寫給mybatis小白的入門指南

mybatis底層原理學習(一):SqlSessionFactory和SqlSession的建立過程
跳進去,發現最終執行的是如下程式碼:

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      // 初始化mybatis基本配置
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      // 建立SqlSessionFactory
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }
複製程式碼

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);這行程式碼會初始化好資料來源,事務管理等mybatis基本配置。最後,呼叫如下方法建立SqlSessionFactory

public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }
複製程式碼

可以知道,SqlSessionFactory持有mybatis的基本配置內容。
講完了 SqlSessionFactory的建立過程,那麼,SqlSessionFactory又是如何獲取SqlSession的呢?我們在獲取SqlSession的地方Debug:

mybatis底層原理學習(一):SqlSessionFactory和SqlSession的建立過程
跳進去,發現最終會執行下面程式碼:

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      // 獲取配置檔案的environments節點配置資訊
      final Environment environment = configuration.getEnvironment();
      // 獲取事務管理工廠
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      // 獲取事務管理例項
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      // 獲取執行器(用於執行CRUD操作)
      final Executor executor = configuration.newExecutor(tx, execType);
      // 建立SqlSession例項
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
複製程式碼

分析程式碼知道,每次開啟一個SqlSession都會繫結一個事務管理例項,執行器例項。 到此,我們分析完了SqlSessionFactory和SqlSession的建立過程。

更多文章,我會在個人微信公眾號第一時間釋出,歡迎關注:深夜程猿

mybatis底層原理學習(一):SqlSessionFactory和SqlSession的建立過程

相關文章