
接下来的几篇文章,将会围绕配置文件的解析进行,这篇文章重点讲述SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的作用
回顾一下MyBatis的测试启动类。
public static void main(String[] args) throws IOException {
Reader reader = Resources.getResourceAsReader("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Person> persons = sqlSession.selectList("com.lightingsui.mapper.IPersonMapper.selectAll");
persons.forEach(System.out::println);
}
作用:SqlSessionFactoryBuilder主要就是构建SqlSessionFactory,即SqlSession的工厂,内部会把上一步的流解析成Configuration,然后根据Configuration构建SqlSessionFactory。
解析流程
SqlSessionFactoryBuilder内部并没有构造函数,而是通过build方法进行处理,内部存在多个重载的build方法。

build()方法
build方法内部其实算作两个流派,一个是Reader流派,另一个为InputStream流派,本质上的区别就是构建XMLConfigBuilder的方式不同。下面就以Reader流派的方式举例。
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
// 构建XML解析器
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
// 调用另一个重载的build方法
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.
}
}
}
方法共有3个参数:
- reader
- 配置文件到的传输流
- environment
- properties
environment
environment的作用与在xml中配置environments的default属性是一致的。作用就是选择一个默认的连接。
<!-- 设置一个默认的连接环境信息 -->
<environments default="mysql_developer">
<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
存在一个问题,如果在xml配置了,但是通过代码指定了environment,那么将使用哪个呢,其实透过XmlConfigBuilder源代码就可以知道(在后面的文章中),会优先使用通过代码指定的environment。
properties
properties的作用和在xml中指定的properties的作用是一致的。加载一些数据库的连接信息。
<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>
那么就也存在上面environment的问题,优先使用xml还是代码的配置,结果为优先使用代码中指定的properties,将会在后面的XmlConfigBuilder源码解析的文章中进行深入了解。
在上面的build方法中,最后又调用了另一个被重载的build方法,而传递的参数为parser.parse(),此方法的返回值为Configuration对象,Configuration为MyBatis全程都存在的配置信息。

此重载的方法返回了一个DefaultSqlSessionFactory(会在后面的源码剖析文章中出现),即SqlSessionFactory默认的实现类,内部是通过Configuration构架出来的。
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}