SqlSessionFactory(二)

本文深入探讨了MyBatis中SqlSessionFactory的创建过程,包括如何通过SqlSessionFactoryBuilder构造SqlSessionFactory,以及其内部如何利用Configuration配置信息生成SqlSession。

从上一篇中,我们找到了我们的切入点SqlSessionFactory,那么现在我们就来会会它.

(注:本文中出现的代码全是出自mybatis-3.2.6版本的源码)

SqlSessionFactory在mybatis被定义为一个接口,在实际使用时,我们一般会通过SqlSessionFactoryBuilder的 build方法来构造一个SqlSessionFactory:

  // Reader是配置文件的输入流
  public SqlSessionFactory build(Reader reader) {
    return build(reader, null, null);
  }

  public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      // parser.parse()方法将xml文件中的配置信息转化为Configuration对象
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

  // 该类中还有其他重载的build方法,但是最终都会调用该方法,传入一个Configuration
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

从上述代码我们得知,SqlSessionFactory默认的实现为DefaultSqlSessionFactory,而DefaultSqlSessionFactory中最主要的也是唯一一个成员变量也就是Configuration.

我们也知道SqlSessionFactory的作用就是用来生成一个SqlSession,因为从上篇文章中的例子来看,我们最终是通过调用SqlSession的方法去和数据库进行交互,那么我们现在来看看DefaultSqlSessionFactory生成SqlSession的代码:

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

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

  public SqlSession openSession(Connection connection) {
    return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);
  }

  public SqlSession openSession(ExecutorType execType, Connection connection) {
    return openSessionFromConnection(execType, connection);
  }

  ......

DefaultSqlSessionFactory中还有很多openSession的重载方法,但是实际上最终都是去调用openSessionFromDataSource方法openSessionFromConnection方法,我们继续看这两个方法的代码:

  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);
      // 最终返回的SqlSession是DefaultSqlSession
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx);
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

  private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
    try {
      boolean autoCommit;
      try {
        autoCommit = connection.getAutoCommit();
      } catch (SQLException e) {
        autoCommit = true;
      }      
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      final Transaction tx = transactionFactory.newTransaction(connection);
      final Executor executor = configuration.newExecutor(tx, execType);
      // 最终返回的SqlSession是DefaultSqlSession
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

从上述代码我们可以看出,实际上我们最终要使用的SqlSession是DefaultSqlSession,并且DefaultSqlSession传入了Configuration(xml文件转换的Configuration信息),Executor(最终由该类去执行sql语句)autoCommit(是否自动提交).

看到这里,相信大家和我一样都有点混乱了,刚找好的SqlSessionFactory切入点又散开了,出现了Configuration,Executor.
而在生成Executor时,又出现了Transaction,TransactionFactory等一系列相关类.不过不要紧,我们可以发现,核心都是围绕着Configuration类的,所以我们先看Configuration,所以,我们就要看看刚开始的parser.parse()方法是把xml配置文件转化为怎么样的一个Configuration类.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值