天天看點

聊聊Mybatis的SqlSession

聊聊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);
           
  1. 擷取Environment對象
  2. 通過Environment對象擷取TransactionFactory對象
  3. 通過事務工廠建立事務對象,傳入參數是Connection對象
  4. 傳入事務對象參數建立出Executor對象
  5. 建立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());
           

總結