1. 程式人生 > >mybatis 3.4.2 DefaultSqlSessionFactory的優化版SqlSessionManager

mybatis 3.4.2 DefaultSqlSessionFactory的優化版SqlSessionManager

d前面介紹 DefaultSqlSessionFactory 可以獲取操作SQL的 session例項。

從下面的程式碼可以看出,每次呼叫openSession 的時候,都會建立一個新的DefaultSession的例項。

  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      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); } 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(); } }

SqlSessionManager是對 DefaultSqlSessionFactory的一個封裝。

 public
static SqlSessionManager newInstance(SqlSessionFactory sqlSessionFactory) { return new SqlSessionManager(sqlSessionFactory); }

寫錯了吧?怎麼是 SqlSessionManager 封裝 SqlSessionFactory, SqlSessionManager是管理session的吧!

沒錯!

來看個圖:

Created with Raphaël 2.1.0開始配置檔案 mapping/mybatis-config.xml 輸入流 InputStream inputStream =Resources.getResourceAsStream("mapping/mybatis-config.xml"); SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSessionManager sessionManager =new SqlSessionManager(sqlSessionFactory);結束

SqlSessionFactoryBuilder 負責接收mybatis-config.xml的輸入流,建立 DefaultSqlSessionFactory 例項。

DefaultSqlSessionFactory實現了 SqlSessionFactory 介面。

SqlSessionManager實現了SqlSessionFactory介面,又封裝了 DefaultSqlSessionFactory。

這裡寫圖片描述

這裡寫圖片描述

Java的代理模式,或者裝飾者模式!

與DefaultSqlSessionFactory不同的是,SqlSessionManager提供了一個本地執行緒變數,每當通過startManagedSession()獲得session例項的時候,會在本地執行緒儲存session例項。這是其一不同。

  public void startManagedSession() {
    this.localSqlSession.set(openSession());
  }

其二,SqlSessionManager 實現了Session介面。意味著,SqlSessionManager集成了 sqlSessionFactory和session 的功能。通過SqlSessionManager,開發者可以不在理會SqlSessionFacotry的存在,直接面向Session程式設計。

SqlSessionManager 內部提供了一個sqlSessionProxy,這個sqlSessionProxy提供了所有Session介面的實現,而實現中正是使用了上面提到的本地執行緒儲存的session例項。

這樣,在同一個執行緒實現不同的sql操作,可以複用本地執行緒session,避免了DefaultSqlSessionFactory實現的每一個sql操作都要建立新的session例項。

這裡寫圖片描述