Mybatis源码阅读笔记(一)SqlSession的创建

300 阅读2分钟

SqlSesssion由SqlSessionFactory创建,而SqlSessionFactory由SqlSessionFactoryBuilder对象产生,下面开始分析一下其创建过程

SqlSessionFactory创建

SqlSessionFactoryBuilder这个类只有一个方法,即build()方法,但是重载了很多版本,这里采用的设计模式为建造者模式。

SqlSessionFactoryBuilder
无论如何,最终都将调用 build(Configuration config),Configuration为全局配置对象,封装了所有的配置信息。 该方法创建了一个DefaultSqlSessionFactory对象,构造函数仅仅是将config赋值

public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

如果采用XML方式配置Mybatis,将会先调用build(InputStream inputStream, String environment, Properties properties)这个方法

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

parse.parse()返回的是一个Configuration对象,其内部对调用parseConfiguration(XNode root)XML配置文件进行解析,

private void parseConfiguration(XNode root) {
    try {
      Properties settings = settingsAsPropertiess(root.evalNode("settings"));
      //issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      loadCustomVfs(settings);
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

SqlSession创建

可以使用上文已经创建好的工厂对象的openSession()方法产生SqlSession,同样这个方法也重载了很多版本,最终会调用

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

execType选定执行器[1]的类型,level决定事物的隔离级别,autoCommit决定是否自动提交(默认不自动提交)最终将调用下面的方法

private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
    try {
      boolean autoCommit;
      try {
        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);
      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();
    }
  }

两个方法根据传进的参数构造好相应的configuration, executor, autoCommit,调用new DefaultSqlSession(configuration, executor, autoCommit)创建SqlSession对象


  1. 执行器,mybatis的调度中心,负责sql生成和查询缓存维护,mybatis重要组件之一 ↩︎