关于java:Mybatis源码分析五获取sqlSession

4次阅读

共计 4903 个字符,预计需要花费 13 分钟才能阅读完成。

构建 sqlSessionFactory 下一步就是获取 sqlSession,代码如下:

SqlSession sqlSession = sqlSessionFactory.openSession();

SqlSessionFactory 有两个实现类,SqlSessionManager 和 DefaultSqlSessionFactory。

由上篇文章可知,在

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

中,new 了一个 DefaultSqlSessionFactory 对象,咱们具体介绍下 DefaultSqlSessionFactory 的次要办法。

5.1 DefaultSqlSessionFactory

DefaultSqlSessionFactory 是一个具体工厂类, 次要提供了两种创立 DefaultSqlSession 形式。一种形式是通过数据源获取数据库连贯并创立 Excutor 对象以及 DefaultSqlSession 对象,源代码如下:

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      // 依据 DataSource 对象创立 Transaction 对象
      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();}
  }

另一种形式是依据用户提供的连贯对象获取数据库连贯并创立 Excutor 对象以及 DefaultSqlSession 对象,其中的主动提交形式也是采纳的 Connection 对象中的。源代码如下:

private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
    try {
      boolean autoCommit;
      try {
        // 应用 Connection 对象的主动提交形式
        autoCommit = connection.getAutoCommit();} catch (SQLException e) {
        // Failover to true, as most poor drivers
        // or databases won't support transactions
        autoCommit = true;
      }
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      // 依据 Connection 对象创立 Transaction 对象
      final Transaction tx = transactionFactory.newTransaction(connection);
      final Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {throw ExceptionFactory.wrapException("Error opening session.  Cause:" + e, e);
    } finally {ErrorContext.instance().reset();}
  }

二者的区别只有下面两点,即正文中的语句。
本文的例子调用的是第一个办法,该办法次要分四步:
1. 从 configuration 中获取 Environment 对象。
2. 从 Environment 对象获取 TransactionFactory 对象。
3. 应用 TransactionFactory 对象创立 Transaction 对象。
4. 依据 Transaction 对象创立 Executor 对象。
5. 依据 Executor 对象创立 DefaultSqlSession 对象。

5.2 Environment

Environment 对象是 XMLConfigBuilder 对象的 parse() 办法进行结构的。具体的执行者是 XMLConfigBuilder 外部的公有办法 environmentsElement()。它有以下几个字段:

  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;

对应配置文件中的 <environment> 节点。

 <!-- id:惟一标识 -->
        <environment id="test">
            <!-- 事务管理器,JDBC 类型的事务管理器 -->
            <transactionManager type="JDBC" />
            <!-- 数据源,池类型的数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://xxx/xxx" />
                <property name="username" value="xxx" />
                <property name="password" value="xxx" />
            </dataSource>
        </environment>

通过断点能够看到,字段的值和下面的配置一一对应。

5.3 TransactionFactory 与 Transaction

TransactionFactory 对象是从下面的 Environment 对象获取的。TransactionFactory 是创立 Transaction 对象的工厂,它有两个实现类。一个是 JdbcTransactionFactory 用来创立 JdbcTransaction,另一个是 ManagedTransactionFactory 用外创立 ManagedTransaction。

Transaction 有两个实现类一个是 JdbcTransaction,另一个是 ManagedTransaction。

本文例子配置文件中 <transactionManager type=”JDBC” />
所以应用的是 JdbcTransaction.
Transaction 次要有以下几个接口。

JdbcTransaction 次要的字段如下:

  // 数据库连贯
  protected Connection connection;
  // 数据源
  protected DataSource dataSource;
  // 数据库隔离级别
  protected TransactionIsolationLevel level;
  // 是否主动提交
  protected boolean autoCommit;

ManagedTransaction 和 JdbcTransaction 比拟相似,然而没有实现 commit() 和 rollback() 办法。

5.4 Executor

在 openSessionFromDataSource 办法中创立 Transaction 对象之后,会依据 tx 创立一个 Executor, 语句如下:

 final Executor executor = configuration.newExecutor(tx, execType);

configuration 的 newExecutor 办法次要作用是依据 execType 来创立不同类型的 Executor 对象,并通过代理的办法执行 interceptor。代码如下:

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    // 如果没有指定 executorType,则应用 ExecutorType.SIMPLE,//defaultExecutorType 是一个常量,值也是 ExecutorType.SIMPLE
    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 { // 因为 ExecutorType.SIMPLE == executorType,所以走这个分支
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {// 默认是 true, 能够通过 <settings> 标签扭转
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

由下面代码看出先 new 了一个 SimpleExecutor,而后被 CachingExecutor 代理,而后被 interceptor 代理。假如有三个拦截器,配置程序为 interceptor1、interceptor2、interceptor3 最初的执行关系是这样的:interceptor3(interceptor2(interceptor1(CachingExecutor(SimpleExecutor()))))

plugin3 before
plugin2 before
plugin1 before
caching ...
simpleExecutor ...
plugin1 after
plugin2 after
plugin3 after

5.5 DefaultSqlSession

最初一步是依据 Executor 对象创立 DefaultSqlSession 对象。
DefaultSqlSession 就 SqlSession 的默认实现类,属于接口层。次要性能是数据库表的增删改查。

正文完
 0