mybatis运行原理--sqlSessionFactory
根据mybayis-config.xml的Resources经过解析,把所有的mapper.xml解析封装成MappedStatement,所有结果统一放入Configuration,最后得到defaultSqlSessionFactory.
这里第五步通过mappers的配置的方法有两种,一种是package,将包下的class也就是我们的mapperInterface添加到configuration中,因为mybatis要求我们将接口和xml文件在同一路径下,后续根据class和xml中的namespace对应就可以找到对应的xml配置文件了。
另外一种就是列举所有的xml路径。通过resouce、url、class三种,resouce、url需要的是mapper.xml,在这个过程中也就会解析xml中定义的namespace、resultMap、sql标签等。sql标签封装成mappedStatement,后续通过namespace就可以找到对应的mapper接口,通过sql的id找到对应接口的方法。class的方式同package性质类似。
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
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);
try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource,
configuration.getSqlFragments());
mapperParser.parse();
}
} else if (resource == null && url != null && mapperClass == null) {
ErrorContext.instance().resource(url);
try (InputStream inputStream = Resources.getUrlAsStream(url)) {
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url,
configuration.getSqlFragments());
mapperParser.parse();
}
} else if (resource == null && url == null && mapperClass != null) {
Class<?> mapperInterface = Resources.classForName(mapperClass);
configuration.addMapper(mapperInterface);
} else {
throw new BuilderException(
"A mapper element may only specify a url, resource or class, but not more than one.");
}
}
}
}
}