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实例化的过程。
*/