天天看點

筆記-mybatis之openSession()

mybatis之openSession()

前面我們已經介紹到了mybatis的簡單應用以及mybatis是怎麼建立SqlSessionFactory的

連結: mybatis初識

連結: mybatis之SqlSessionFactory

回到我們代碼

package test;

import entity.Cust;
import lombok.extern.slf4j.Slf4j;
import mapper.CustMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

@Slf4j
public class MybatisTest {
    public static void main(String[] args) {
        try{
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession = sessionFactory.openSession();
            Cust cust = sqlSession.selectOne("mapper.CustMapper.selectListByCode","001");
            /*CustMapper mapper = sqlSession.getMapper(CustMapper.class);
            Cust cust = mapper.selectListByCode("001");*/
            log.info(cust.toString());
        }catch (Exception e){
            log.error(e.getMessage());
        }
    }
}
           

建立SqlSessionFactory之後,我們點選openSession()方法進入到DefaultSqlSessionFactory類(前面已經分析了建立SqlSessionFactory方法源碼的最後一段代碼就是new 了一個DefaultSqlSessionFactory對象)。進入

@Override
  public SqlSession openSession() {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
  }
           

打開,點選進入到

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();
    }
  }
           

代碼第一句是從我們配置對象中擷取環境配置資訊,你也可以了解為從mybatis-config.xml擷取environment節點資訊。

代碼第二,三句就是擷取資料庫事務資訊。

代碼第四句初始化了一個執行器

代碼最後一句就是傳回一個DefaultSqlSession對象。

也就是說

SqlSession sqlSession = sessionFactory.openSession();
           

其實是

拿到SqlSession 進行對我們的執行器Executor進行初始化 。

在初始化執行器的時候,有一個很重要的方法

executor = (Executor) interceptorChain.pluginAll(executor);
           

這個涉及到了責任鍊,如果大家對責任鍊不熟悉,推薦大家看這篇文章

連結: Mybatis Plugin 插件(攔截器)原理分析.

們項目用到的pageHelper就是基于責任鍊開發的

相應的debug鍊

org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession()
 >org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource
  >org.apache.ibatis.transaction.TransactionFactory.newTransaction(javax.sql.DataSource, org.apache.ibatis.session.TransactionIsolationLevel, boolean)
    >org.apache.ibatis.session.Configuration.newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)
      >org.apache.ibatis.executor.SimpleExecutor
        >org.apache.ibatis.executor.CachingExecutor 
          >org.apache.ibatis.plugin.InterceptorChain.pluginAll
           

繼續閱讀