Mybatis源码分析——SqlSession的创建过程

Mybatis源码分析——SqlSession的创建过程

一、创建sqlSession的流程


private static String resource="mybatis-config.xml";
public static SqlSession getSqlSession() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream(resource);
    //先创建工厂创建类
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
   //通过工厂创建类创建工厂
    SqlSessionFactory build = sqlSessionFactoryBuilder.build(inputStream);
    //通过工厂得到sqlsession实体类
    return  build.openSession(true);
}

二、分析代码

1. 查看bulid()源码

//该方法将environment,properties赋了空置并且调用另一个bulid方法
public SqlSessionFactory build(InputStream inputStream) {
  return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    //首先创建一个XMLConfigBuilder对象
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
    //调用了parse()方法得到了一个 Configuration类 并且再次调用了下面的bulid方法
      return build(parser.parse());
								}
  // DefaultSqlSessionFactory是 SqlSessionFactory的默认实现类
  //至此,SqlSessionFactory实例化完成
  public SqlSessionFactory build(Configuration config) {
    //返回了默认实现类并进行了初始化
      return new DefaultSqlSessionFactory(config);
  }
}
继续查看bulid方法中parse()方法
public Configuration parse() {
    //防止parse被同一个实例多次调用
  if (parsed) {
    throw new BuilderException("Each XMLConfigBuilder can only be used once.");
  }
  parsed = true;
    //调用evalNode方法得到 configuration节点的XNode对象
    //然后调用 parseConfiguration()方法对XNode进行处理
  parseConfiguration(parser.evalNode("/configuration"));
  return configuration;
}
//在parseConfiguration()方法中,对于<configuration>标签的子节点,都有一个单独的方法处理
//具体怎么操作标签里的元素可以继续查看实现,这里不讲述
 private void parseConfiguration(XNode root) {
    try {
      // issue #117 read properties first
      propertiesElement(root.evalNode("properties"));
      //settings是通过一些属性来控制MyBatis运行时的一些行为。例如,指定日志实现等
        Properties settings = settingsAsProperties(root.evalNode("settings"));
      loadCustomVfs(settings);
      loadCustomLogImpl(settings);
        //typeAliases 取别名
      typeAliasesElement(root.evalNode("typeAliases"));
        //plugins 用户的一些插件
      pluginElement(root.evalNode("plugins"));
        //还有一些是通过 configuration的工厂类来创建具体实例的
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
      settingsElement(settings);
      // read it after objectFactory and objectWrapperFactory issue #631
        //environments:用于配置MyBatis数据连接相关的环境及事务管理器信息。
      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);
    }
  }
分析源码得到

XMLConfigBuilder调用parse()方法完成了对configuration的初始化

MyBatis通过XMLConfigBuilder类完成Configuration对象的构建工作

分析源码得到

在创建SqlsessionFactory工厂时就已经完成对了Configuration 的初始化和 DefaultSqlSessionFactory的初始化

由此可知,DefaultSqlSessionFactory是SqlsessionFactory默认实现类

2. 查看openSession()源码

由于DefaultSqlSessionFactory是SqlsessionFactory默认实现类 所以openSession的方法实现还要通过DefaultSqlSessionFactory查看

//由此可见 默认是不开启自动提交事务的
public SqlSession openSession() {
  return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
    //当参数是true 才会开启自动提交
    //最终都调用了openSessionFromDataSource()方法
  public SqlSession openSession(boolean autoCommit) {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);
  }
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
        //之前已经说了在创建sqlsessionFactory时候就已经完成了configuration的初始化
        //获取Mybatis主配置文件的环境信息
      final Environment environment = configuration.getEnvironment();
        //创建事务工厂
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
        //创建事务管理器,通过传入的参数autoCommit决定是否开启自动事务提交
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      //根据Mybayis主配置文中指定的Executor类创建Executor实例   
        /*有三个值
        SIMPLE:基础的Executor,能够完成基本的增删改查操作  默认值
        REUSE:ResueExecutor对JDBC中的Statement对象做了缓存,提升系统性能
        BATCH: 完成批量数据库操作
        */
      final Executor executor = configuration.newExecutor(tx, execType);
        //返回 创建DefaultSqlSession实例
        //DefaultSqlSession是sqlsession接口的实现类
      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();
    }
  }
分析源码得到

opopenSession方法创建事务工厂,创建事务管理器和Executor实例

openSession的数据库操作都是由Executor实例完成

最后返回了DefaultSqlSession类

DefaultSqlSession是sqlsession接口的实现类

总结:

/*
SqlSession的创建过程拆可分为3个阶段:
Configuration实例的创建过程、
SqlSessionFactory实例的创建过程
和SqlSession实例化的过程。
*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值