上篇文章和大家简单入门了mybatis的增删改查操作:写给mybatis小白的入门指南。这篇文章就从源码角度分析一下mybatis的SqlSessionFactory的创建过程
SqlSessionFactory是SqlSession的创建工厂,每一个SqlSession实例代表应用程序和数据库的一次连接。 在整个应用当中,我们应该只创建一个SqlSessionFactory实例,但是可以有多个SqlSession实例。那么,SqlSessionFactory是怎么创建出来的呢?下面我们看一张时序图:
首先是读取mybatis配置文件到内存中,然后通过XMLConfigBuilder初始化基本配置,由SqlSessionFactoryBuilder来创建SqlSessionFactory,由SqlSessionFactory获取SqlSession。
那么,在创建SqlSessionFactory过程,mybatis具体做了什么?我们在创建SqlSessionFactory的地方Debug进去(代码用的是上一篇文章的代码:写给mybatis小白的入门指南)
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
// 初始化mybatis基本配置
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// 创建SqlSessionFactory
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.
}
}
}
复制代码
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
这行代码会初始化好数据源,事务管理等mybatis基本配置。最后,调用如下方法创建SqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
复制代码
可以知道,SqlSessionFactory持有mybatis的基本配置内容。
讲完了 SqlSessionFactory的创建过程,那么,SqlSessionFactory又是如何获取SqlSession的呢?我们在获取SqlSession的地方Debug:
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
// 获取配置文件的environments节点配置信息
final Environment environment = configuration.getEnvironment();
// 获取事务管理工厂
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// 获取事务管理实例
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 获取执行器(用于执行CRUD操作)
final Executor executor = configuration.newExecutor(tx, execType);
// 创建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();
}
}
复制代码
分析代码知道,每次打开一个SqlSession都会绑定一个事务管理实例,执行器实例。 到此,我们分析完了SqlSessionFactory和SqlSession的创建过程。
更多文章,我会在个人微信公众号第一时间发布,欢迎关注:深夜程猿