当我们在使用mybatis时,我们通常会和Spring一起使用,就会使用以下配置方式,从而使用mybatis
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进行关闭