真的,MyBatis 核心源码入门看这个就够了(二)


上接 《真的,MyBatis 核心源码入门看这个就够了(一)


2 SqlSession

SqlSession对象的创建过程
SqlSession对象的创建过程

程序每一次操作数据库,都需要创建一个会话,我们用openSession() 来创建。
在上一篇文章的demo:

```java 
    @org.junit.jupiter.api.Test
    void queryBySn() throws IOException {
        //1 读取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        //2 加载解析配置文件并获取SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        //3 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //4 通过SqlSession中提供的API方法来操作数据库
        DeviceMapper deviceMapper = sqlSession.getMapper(DeviceMapper.class);
        Device device = deviceMapper.queryBySn(Device.builder().sn("2234567").build());
        System.out.println(device);
        //5 关闭会话
        sqlSession.close();
    }

通过 DefaultSqlSessionFactory 的openSession 来创建。

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

首先会获取默认的执行器类型,默认的是simple

public class Configuration {
  ......
  protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;   
  .....
}

继续进入到 DefaultSqlSessionFactory的 openSessionFromDataSource方法:

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

我们在解析 environment 标签的时候,创建了TransactionFactory对象。

public class XMLConfigBuilder extends BaseBuilder {
  ......
  private void environmentsElement(XNode context) throws Exception {
    if (context != null) {
      if (environment == null) {
        environment = context.getStringAttribute("default");
      }
      for (XNode child : context.getChildren()) {
        String id = child.getStringAttribute("id");
        if (isSpecifiedEnvironment(id)) {
          // 事务工厂
          TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
	......

根据事务工厂和默认的执行器类型,创建执行器:
final Executor executor = configuration.newExecutor(tx, execType);

public class Configuration {
  ......
  public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      executor = new ReuseExecutor(this, transaction);
    } else {
      // 默认 SimpleExecutor
      executor = new SimpleExecutor(this, transaction);
    }
    // 二级缓存开关,settings 中的 cacheEnabled 默认是 true
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    // 植入插件的逻辑,至此,四大对象已经全部拦截完毕
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }
  ......
}

最后返回的是一个 DefaultSqlSession对象。
return new DefaultSqlSession(configuration, executor, autoCommit);
在这个DefaultSqlSession对象中包括了Configuration 和 Executor对象。

以上2 章节创建会话的过程中,我们获得了一个DefaultSqlSession,里面包含了一个Executor,Executor是SQL的实际执行对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值