05 Mybatis源码篇---XML配置之mappers 映射器
这里我简单的讲述一下,在创建SqlSessionFactory对象的时候,是如何解析XML配置文件,并完成加载。
首先从解析MyBatis配置文件configuration节点及子节点时,调用mapperElement来解析mappers。
/**
* 解析Mappers节点及一下节点
*/
mapperElement(root.evalNode("mappers"));
/**
* 解析XML配置文件mappers节点
* @param parent
* @throws Exception
*/
private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
/**
* mappers 节点下,配置我们的mapper映射文件, 所谓的mapper映射文件,就是让mybatis 用来建立数据表和javabean映射的一个桥梁。
* 在我们实际开发中,通常一个mapper文件对应一个dao接口, 这个mapper可以看做是dao的实现。所以,mappers必须配置。
* 对于mapper的配置,跟typeAliases相同,有两种方式
*<mappers>
* <mapper resource="demo1/UserMapper.xml"/>
* <mapper class="hzq.mybatis.source.demo1.dao.IUserDao"/>
* <mapper url="file:///var/demo1/UserMapper.xml"/>
* <package name="hzq.mybatis.source.demo1.dao"/>
</mappers>
* mapper 和 package两种方式,但是对于mapper配置,又有三种不同的引用方式,见下面源码
* package加载的是所有的接口的class文件“Register all interfaces in a package as mappers”,要求跟<mapper class="hzq.mybatis.source.demo1.dao.IUserDao"/>这种配置方式一样
* mapper:
* resource ---“Using classpath relative resources” 使用相对路径
* url ---- “Using url fully qualified paths” 使用全路径
* class -- “ Using mapper interface classes ” 使用mapper文件的接口类,通过class指定接口,进而将接口与对应的xml文件形成映射关系,但是必须保证接口和mapper文件同名(不区分大小写)
*
*/
if ("package".equals(child.getName())) {
/**
* 获取MyBatis配置文件的包名称
*/
String mapperPackage = child.getStringAttribute("name");
/**
* 解析package目录下面的Mapper文件,并加载到configuration
*/
configuration.addMappers(mapperPackage);
} else {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
/**
* mapper 配置方式,class,resource ,url 3个任取其一
*/
if (resource != null && url == null && mapperClass == null) {
// resource 配置方式
ErrorContext.instance().resource(resource);
/**
* 读取mapper文件
*/
InputStream inputStream = Resources.getResourceAsStream(resource);
/**
* mapper映射文件都是通过XMLMapperBuilder解析
*/
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
} else if (resource == null && url != null && mapperClass == null) {
//url 配置方式
ErrorContext.instance().resource(url);
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 配置方式
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.");
}
}
}
}
}
针对与Mpper映射文件具体是如何解析的,在研究完Mpper映射中的元素,我会将详细的流程展现给大家。