聊聊Mybatis的SqlSession
SqlSessionFactory接口是用來建立SQLSession的,它是一個接口,預設實作類是DefaultSqlSessionFactory,DefaultSqlSessionFactory中建立SqlSession有兩種方式:
通過連接配接資訊建立SqlSession
一種是調用openSessionFromConnection()來擷取SqlSession,也就是通過Connection來建立SqlSession,關鍵代碼
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
final Transaction tx = transactionFactory.newTransaction(connection);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
- 擷取Environment對象
- 通過Environment對象擷取TransactionFactory對象
- 通過事務工廠建立事務對象,傳入參數是Connection對象
- 傳入事務對象參數建立出Executor對象
- 建立DefaultSqlSession對象來建立SqlSession
通過資料源建立SqlSession
另一種方法是openSessionFromDataSource()方法,也就是通過資料源來擷取SqlSession,關鍵代碼:
final Environment environment = configuration.getEnvironment();
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
final Executor executor = configuration.newExecutor(tx, execType);
return new DefaultSqlSession(configuration, executor, autoCommit);
整體和第一種一樣,隻是第三步建立事務對象時候,傳入參數是DataSource對象
SqlSession接口是一個重要的接口,它提供增删改查的的執行接口和事務管理的接口,預設實作類是DefaultSqlSession,DefaultSqlSession有個Executor成員變量,通過這個執行器進行事務的管理和sql的執行,這裡用到了政策模式,Executor就是政策類,它的子類就是具體的政策類,DefaultSqlSession根據不同的政策選擇不同Executor來進行事務管理和sql執行,DefaultSqlSession的增删改查的所有方法都是通過Executor執行個體來進行執行的
SqlSessionManager
SqlSessionManager實作了SqlSessionFactory接口和SqlSession接口,它既可以建立SQLSession,又能對資料庫操作,它是SqlSessionFactory的裝飾類,SqlSessionManager可以通過openSession()調用sqlSessionFactory建立SqlSession
@Override
public SqlSession openSession() {
return sqlSessionFactory.openSession();
}
SqlSessionManager有個ThreadLocal成員變量:
ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<>();
通過ThreadLocal可以調用startManagedSession()實作目前線程和SqlSession的綁定:
public void startManagedSession() {
this.localSqlSession.set(openSession());
}
this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(
SqlSessionFactory.class.getClassLoader(),
new Class[]{SqlSession.class},
new SqlSessionInterceptor());