SqlSessionFactoryBuilder--->XMLConfigBuilder---> XMLMapperBuilder---(桥梁)MapperBuilderAssistant--->XMLStatementBuilder(parseStatementNode方法)--(桥梁)MapperBuilderAssistant(addMappedStatement方法)-->MappedStatement.Builder--->MappedStatement--->confuguration.addMappedStatement()
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
public Configuration parse() {
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
loadCustomLogImpl(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
//这一步,根据setting解析的结果,设置我们的一些参数,如果没有设置则给默认值。
//我们的配置如下:
/**
<settings>
<setting name="cacheEnabled" value="false"/>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
*/
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
//这一步,解析Mapper.xml
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
/**
<mappers>
<mapper resource="userMapper.xml"/>
</mappers>
*/
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
if ("package".equals(child.getName())) {//子节点 是<package>这样的
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {//我们在这个分支 ,先获取 resource,url,class这三个属性的值
//我们的resource值为:userMapper.xml
//这三个属性值,只能三选一。
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
//我们在这个分支
ErrorContext.instance().resource(resource);
//读取我们的userMapper.xml文件,转为输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建XMLMapper的Builder对象
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragme