天天看点

笔记-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
           

继续阅读