mybatis 最新发布的版本是V3.4.1,发布时间是2016年6月26日。
下面的分析是根据mybatis 3.4.2 的代码做的。
一、启动入口
mybatis的有一个核心配置文件,用于设置全局的一些参数以及个性化定制参数,比如:数据库连接、缓存、sql映射文件等一些信息。
这个核心的文件名称任意,这里参照 这篇文章 的名称,叫做 mybatis-config.xml
1、首先,mybatis-config.xml是一个位于运行环境classpath下mapping目录中的一个文件。
2、其次,将mybatis-config.xml转换为输入流形式
String resource = "mapping/mybatis-config.xml";
InputStream inputStream =Resources.getResourceAsStream(resource);
上面代码中的 Resources 是mybatis提供的一个io读取类。
3、第三,解析配置文件得到配置实例
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream);
Configuration config = parser.parse();
在解析类 XMLConfigBuilder中的解析方法可以看出mybatis-config.xml文件中对应的元素。
- configuration是根元素。
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
- 其他元素是configuration的子元素。
private void parseConfiguration(XNode root) {
try {
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
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);
}
}
4、最后,注入config变量生成mybatis核心对象实例 SqlSessionFactory
SqlSessionFactory ssf =new DefaultSqlSessionFactory(config);
因此,mybatis-config.xml主要是用于配置生成SqlSessionFactory。
mybatis与数据库交互需要用到SqlSession的实例session,每个session完成一个请求的SQL操作。
而通过sqlSessionFactory实例的openSession()方法就可以获得一个SqlSession实例。
二、代码入口
mybatis提供了 SqlSessionFactoryBuilder类,可以直接使用获取SqlSessionFactory实例。
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
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.
}
}
}
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
}
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.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
mybatis 获取 SqlSessionFactory的流程: