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

发布时间:2023年12月28日

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完成。

文章来源:https://blog.csdn.net/weixin_43727372/article/details/135260965
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。