mybatis 源码系列(一) 初始化
通过阅读mybatis的官方文档,我们知道了初始化mybatis的方法有以下两种方法:
- 通过XML文件构建SqlSessionFactory对象,最终创建SqlSession使用对象实例
- 通过Java创建Configuration对象来构建SqlSessionFactory对象
类图
我们先来看mybatis的初始化相关的几个基础类图
几个关键类说明:
- SqlSessionFactoryBuilder:创建SqlSessionFactory对象的唯一类.
- SqlSessionFactory:创建SqlSession对象实例的工厂类,一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例,可以和应用中的DataSource等同处理,一个数据源对应一个SqlSessionFactory对象.
- SqlSession:通过SqlSession对象进行对数据库的操作访问,该类为线程不安全,所以,每次对数据库的操作都需要重新创建SqlSession对象实例,不可将SqlSession对象实例置为全局变量
基于Xml
基于Xml文件来创建SqlSessionFactory对象的方式,通过阅读源码我们知道以下两种
- 提供根据读取XML的InputStream流对象来构建
- 根据读取Xml的Reader流对象来构建.
SqlSessionFactoryBuilder.java
:
public class SqlSessionFactoryBuilder {
/***
* 根据reader对象来构建
* @param reader
* @return
*/
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
/****
* 指定参数构建
* @param reader
* @param environment
* @param properties
* @return
*/
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
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.
}
}
}
//other constucts
/***
* 根据input流来构建
* @param inputStream
* @return
*/
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
/***
* 指定参数构建
* @param inputStream
* @param environment
* @param properties
* @return
*/
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
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.
}
}
}
}
除了根据Reader
和InputStream
,还可以指定相关的environment
和properties
属性
此时,初始化的代码:
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
非XML
非XML的方式是开发者在外部首先初始化创建好相应的Configuration
对象实例,然后调用SqlSessionFactoryBuilder
的build(Configuration confg)
方法来进行创建
/***
* 最终通过Configuration对象构建SqlSessionFactory的方法,前面的各种构造函数都是通过读取流Xml对象,最终转换为Configuration对象
* 调用build(config)来构建SqlSessionFactory
* @param config
* @return
*/
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
最终初始化代码应该是这样:
Configuration configuration = new Configuration(environment);
//other init operate...
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
Configuration
通过以上两种初始化的方式,我们大致了解到,mybatis的配置核心类Configuration
,该类是mybatis的配置核心.不管是创建SqlSession或者SqlSessionFactory,都需要基于Configuration
来操作.