Mybatis工作原理分析(一)

 一、引言

当我们在使用mybatis时,我们通常会和Spring一起使用,就会使用以下配置方式,从而使用mybatis

<!-- 配置mybatis的工厂,即sqlSessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<!-- 核心配置文件的位置 -->
		<property name="configLocation" value="classpath:spring/SqlMapConfig.xml"/>
	</bean>

 二、源码分析

mybatis框架   在单独使用mybatis时,   源码进行分析

1、mybatis将配置文件保存到configuration对象中,作用是将配置文件加载到内存中,加快配置文件的读取速度

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");

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

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
//通过xmlconfigbulider解析器对配置文件进行解析
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      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.
      }
    }
  }

xmlconfigbuilder的parse方法,返回的是Configuration对象

public Configuration parse() {
  if (parsed) {
    throw new BuilderException("Each XMLConfigBuilder can only be used once.");
  }
  parsed = true;
  parseConfiguration(parser.evalNode("/configuration"));
//最后返回的是Configuration对象
  return configuration;
}

2、将configuration作为属性交给defaultsqlsessionFactory类实例对象

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

3通过sqlsessionfactory创建sqlsession

通过sqlsessionfactory的opensession方法调用

public SqlSession openSession() {
  return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
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);
//返回一个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();
  }
}

 4sqlsession调用update方法

 

 

public int update(String statement, Object parameter) {
  try {
//dirty的作用是是否决定提交或者回滚
    dirty = true;
    MappedStatement ms = configuration.getMappedStatement(statement);
    return executor.update(ms, wrapCollection(parameter));
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

 注意到这里为止,sql语句还没有提交,仅仅是用statement对象,对sql语句进行定位,并没有进行执行

5、sqlsession调用commit进行提交或者回滚

是通过dirty进行判断是否需要回滚

public void commit(boolean force) {
  try {
    executor.commit(isCommitOrRollbackRequired(force));
    dirty = false;
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

6、最后对sqlsession进行关闭

 

 

 

 

发布了2 篇原创文章 · 获赞 0 · 访问量 756
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览