Mybatis源码(二)— openSession

上一篇中主要介绍了Mybatis解析配置文件的整体流程,并创建了SqlSessionFactory对象,SqlSessionFactory顾名思义就是创建SqlSession的工厂,那么接着往下来,看看sqlSessionFactory.openSession()中都干了些什么。

openSession()方法

开启数据库会话,创建数据库连接的会话对象(事务对象、事务工厂、执行器、如果有插件会进行插件解析)

 		@Test
        public void test02 () {
            // 根据全局配置文件创建出SqlSessionFactory
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // SqlSessionFactory:负责创建SqlSession对象的工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            // SqlSession:表示跟数据库建议的一次会话
            // 获取数据库的会话,创建出数据库连接的会话对象(事务工厂,事务对象,执行器,如果有插件的话会进行插件的解析)
            SqlSession sqlSession = sqlSessionFactory.openSession();
            Emp empByEmpno = null;
            try {
                // 获取要调用的接口类,创建出对应的mapper的动态代理对象(mapperRegistry.knownMapper)
                EmpDao mapper = sqlSession.getMapper(EmpDao.class);
                // 调用方法开始执行
                empByEmpno = mapper.findEmpByEmpnoAndEname(7369, "SMITH");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                sqlSession.close();
            }
            System.out.println(empByEmpno);
        }

openSession具体执行流程

  //execType 执行器类型,默认会给定一个SIMPLE Executor
  //level 隔离级别,共NONE、READ_COMMITTED、READ_UNCOMMITTED、REPEATABLE_READ、SERIALIZABLE五种类型
  //autoCommit 事务自动提交 默认false
  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    //
    Transaction tx = null;
    try {
      //获取mybatis-config.xml文件中Environment标签对象
      final Environment environment = configuration.getEnvironment();
      //创建事务工厂
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      //创建Transaction对象
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      //创建Executor
      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();
    }
  }

getTransactionFactoryFromEnvironment
如果没有配置事务工厂,则使用默认的ManagedTransactionFactory,否则根据配置进行创建

 //构建事务工厂
  private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
    //如果没有配置事务工厂,则返回托管事务工厂
    if (environment == null || environment.getTransactionFactory() == null) {
      return new ManagedTransactionFactory();
    }
    return environment.getTransactionFactory();
  }

newExecutor
创建Executor,默认会使用SIMPLE.EXECUTOR

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    //下面两行代码一样,莫得什么不同
    //如果executorType为null,则创建一个SIMPLE的Executor
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    //根据参数,创建不同的Executor
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      executor = new SimpleExecutor(this, transaction);
    }
    //根据配置,看是否开启二级缓存
    //如果开启了缓存,则封装成CachingExecutor
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    //通过插件,可以修改Executor
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

Executor
创建Executor时会调用父类BaseExecutor的构造器,类中有对缓存的设置。

public abstract class BaseExecutor implements Executor {

  private static final Log log = LogFactory.getLog(BaseExecutor.class);

  protected Transaction transaction;
  protected Executor wrapper;

  //延迟队列,线程安全
  protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
  // 一级缓存,用于缓存该Executor对象查询结果集映射得到的结果对象
  protected PerpetualCache localCache;
  // 一级缓存,用于缓存输出类型的参数
  protected PerpetualCache localOutputParameterCache;
  protected Configuration configuration;

  // 用来记录嵌套查询的层数
  protected int queryStack;
  private boolean closed;

  protected BaseExecutor(Configuration configuration, Transaction transaction) {
    this.transaction = transaction;
    this.deferredLoads = new ConcurrentLinkedQueue<>();
    this.localCache = new PerpetualCache("LocalCache");
    this.localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache");
    this.closed = false;
    this.configuration = configuration;
    this.wrapper = this;
  }
 }

CachingExecutor
如果开启了二级缓存,则会对Executor进行一次封装。

public CachingExecutor(Executor delegate) {
    this.delegate = delegate;
    delegate.setExecutorWrapper(this);
  }

总结:
openSession中,只是获取了数据库会话,并创建了事务会话、工厂、执行器。并没有进行数据库的连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值