源码解析:mybatis调用链之获取sqlSession

SqlSession

通过SqlSession sqlSession = sqlSessionFactory.openSession();获取SqlSession实例,

DefaultSqlSessionFactory

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

//从数据源获取数据库连接
  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
        //获取mybatis配置文件中的environment对象
      final Environment environment = configuration.getEnvironment();
      //从environment获取transactionFactory对象
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      //创建事务对象
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      //根据配置创建executor
      final Executor executor = configuration.newExecutor(tx, execType);
      //创建DefaultSqlSession
      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();
    }
  }

openSessionFromDataSource主要分为一下几个步骤:

1、获取mybatis配置文件中的environment对象

final Environment environment = configuration.getEnvironment();

2、从environment获取transactionFactory对象

final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);

3、创建事务对象

tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);

这里以JdbcTransactionFactory(TransactionFactory实现类)为例,获取JdbcTransaction(Transaction实现类)

JdbcTransactionFactory

public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
    return new JdbcTransaction(ds, level, autoCommit);
  }

4、创建Executor对象

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 {
      executor = new SimpleExecutor(this, transaction);
    }
    //如果有<cache>节点,通过装饰器,添加二级缓存的能力
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    //通过interceptorChain遍历所有的插件为executor增强,添加插件的功能
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

1)调用Configuration对象方法newExecutor进行创建,根据executorType选择相应的Executor实现类,这里以选择默认的SIMPLE为例,则选择新建SimpleExecutor对象。

2)判断全局的cacheEnabled值(默认为true),通过装饰器,添加二级缓存的能力。因此,二级缓存配置需要在mybatis-config.xml的cache进行开启。另外从这里,可以看到若是cacheEnabled为false,则executor并未增加二级缓存的能力,表明二级缓存不能使用。

3)通过InterceptorChain的pluginAll方法遍历所有的插件为executor增强,添加插件的功能

InterceptorChain

public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) {
      target = interceptor.plugin(target);
    }
    return target;
  }
  

ThresholdInterceptor一个Interceptor接口的自定义实现类

ThresholdInterceptor

@Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

Plugin类wrap方法,实现InvocationHandler,Interceptor的代理类。在wrap方法中,可以看到,会根据@Intercepts的信息以及目标对象的信息,判断是否需要对该对象进行拦截代理。

Plugin

//静态方法,用于帮助Interceptor生成动态代理
  public static Object wrap(Object target, Interceptor interceptor) {
    //解析Interceptor上@Intercepts注解得到的signature信息
    Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
    Class<?> type = target.getClass();//获取目标对象的类型
    Class<?>[] interfaces = getAllInterfaces(type, signatureMap);//获取目标对象实现的接口(拦截器可以拦截4大对象实现的接口)
    if (interfaces.length > 0) {
      //使用jdk的方式创建动态代理
      return Proxy.newProxyInstance(
          type.getClassLoader(),
          interfaces,
          new Plugin(target, interceptor, signatureMap));
    }
    return target;
  }

注意:Configuration对象中保存有默认的executorType:ExecutorType defaultExecutorType = ExecutorType.SIMPLE;BatchExecutor、ReuseExecutor、SimpleExecutor都继承于BaseExecutor抽象类,BaseExecutor主要用于为一些基础属性如configuration、transaction等赋初始值。

5、创建DefaultSqlSession,获取sqlSession完成。

最近更新

  1. TCP协议是安全的吗?

    2024-01-01 21:36:07       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-01 21:36:07       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-01 21:36:07       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-01 21:36:07       18 阅读

热门阅读

  1. 浅析 Dockerfile 构建缓存:原理与优化方法

    2024-01-01 21:36:07       39 阅读
  2. python弹奏《起风了》

    2024-01-01 21:36:07       38 阅读
  3. 我自己的Mac装机软件推荐!

    2024-01-01 21:36:07       32 阅读
  4. 网络安全领域八大国际认证

    2024-01-01 21:36:07       30 阅读
  5. MySQL第七章:MySQL的基本函数

    2024-01-01 21:36:07       47 阅读
  6. CSS中背景设置——渐变色和放射渐变

    2024-01-01 21:36:07       28 阅读
  7. (C)一些题15

    2024-01-01 21:36:07       28 阅读
  8. springboot中使用mongodb进行简单的查询

    2024-01-01 21:36:07       40 阅读
  9. CMEMS数据下载

    2024-01-01 21:36:07       35 阅读
  10. 功能开发 -- 向埃隆·马斯克学习任务分解

    2024-01-01 21:36:07       38 阅读
  11. 基于SpringBoot的在线互动学习网站

    2024-01-01 21:36:07       39 阅读
  12. C语言学习

    2024-01-01 21:36:07       37 阅读
  13. R_handbook_统计分析

    2024-01-01 21:36:07       30 阅读
  14. 矩阵对角线遍历

    2024-01-01 21:36:07       40 阅读