每个 mybatis 应用都是以一个 SqlSessionFactory
实例为核心的,而 SqlSessionFactory
的生成其实很简单,只需要一下三行代码(基于 XML 配置文件实现):
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
首先需要有 XML 配置文件,然后转成 InputStream
,然后使用SqlSessionFactoryBuilder
生成 SqlSessionFactory
对象。接下来看一下具体做了什么:
首先,调用的是一个 build(InputStream inputStream)
方法:
public SqlSessionFactory build(InputStream inputStream) {return build(inputStream, null, null);
}
可以看到这个方法直接调用了 build(InputStream inputStream, String environment, Properties properties)
方法,后面两个参数传的是null
。看下具体实现:
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.}
}
}
忽略 try...catch...
,首先根据参数 new 了一个XMLConfigBuilder
对象,可以看出这个 XML 解析器装载了一个实现了 EntityResolver
接口的 XMLMapperEntityResolver
对象。然后调用了下一个 build(Configuration config)
方法。看下parser.parse()
:
public Configuration parse() {if (parsed) {throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
// 这里开始解析 XML 配置文件
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
可以看出解析 XML 配置文件的代码是:parseConfiguration(parser.evalNode("/configuration"));
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
// 解析 properties 节点配置
propertiesElement(root.evalNode("properties"));
// 解析 settings 节点配置
Properties settings = settingsAsProperties(root.evalNode("settings"));
// 根据 settings 配置,装载自定义 Vfs
loadCustomVfs(settings);
// 根据 settings 配置,装载对应的日志实现
loadCustomLogImpl(settings);
// 解析别名配置
typeAliasesElement(root.evalNode("typeAliases"));
// 解析插件配置
pluginElement(root.evalNode("plugins"));
// 解析 objectFactory 配置
objectFactoryElement(root.evalNode("objectFactory"));
// 解析 objectWrapperFactory 配置
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
// 解析 reflectorFactory 配置
reflectorFactoryElement(root.evalNode("reflectorFactory"));
// 把 settings 中的属性设置到 configuration 对象中去
settingsElement(settings);
// 解析 environment 配置
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
// 解析 databaseIdProvider 配置,databaseIdProviderElement(root.evalNode("databaseIdProvider"));
// 解析 typeHandlers 配置
typeHandlerElement(root.evalNode("typeHandlers"));
// 解析 mappers 标签配置
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {throw new BuilderException("Error parsing SQL Mapper Configuration. Cause:" + e, e);
}
}
至此,mybatis 配置文件解析完毕,调用 build(Configuration config)
方法生成 SqlSessionFactory
对象:
public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);
}
可以看出,返回的是 DefaultSqlSessionFactory
对象.