上篇文章和大家簡單入門了mybatis的增刪改查操作:寫給mybatis小白的入門指南。這篇文章就從原始碼角度分析一下mybatis的SqlSessionFactory的建立過程
SqlSessionFactory是SqlSession的建立工廠,每一個SqlSession例項代表應用程式和資料庫的一次連線。 在整個應用當中,我們應該只建立一個SqlSessionFactory例項,但是可以有多個SqlSession例項。那麼,SqlSessionFactory是怎麼建立出來的呢?下面我們看一張時序圖:
首先是讀取mybatis配置檔案到記憶體中,然後通過XMLConfigBuilder初始化基本配置,由SqlSessionFactoryBuilder來建立SqlSessionFactory,由SqlSessionFactory獲取SqlSession。
那麼,在建立SqlSessionFactory過程,mybatis具體做了什麼?我們在建立SqlSessionFactory的地方Debug進去(程式碼用的是上一篇文章的程式碼:寫給mybatis小白的入門指南)
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:
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的建立過程。
更多文章,我會在個人微信公眾號第一時間釋出,歡迎關注:深夜程猿