Mybatis 源码学习(二) Mapper 接口和sql的映射
程序员文章站
2022-07-12 22:37:17
...
问题:xml中的sql语句是怎么被映射到Mapper接口的一个方法上的?
弄明白了mapper是如何注册的了以后,发现xml文件中的namespace是关键。实际还是去找那个java接口文件。那么找到了接口文件,注册了mapper那这个mapper又是怎么反过来找到xml中配置的sql的呢?
看mapper注册的代码好想没有发现这个映射关系。从新再看一下源码,这次要顺利很很,很快找到了昨天那一串调用栈。
sqlSessionFactoryBuilder.build(inputStream);
return build(parser.parse());
parseConfiguration(parser.evalNode("/configuration"));
mapperElement(root.evalNode("mappers"));
然后找resource!=null的情况
public void parse() {
if (!configuration.isResourceLoaded(resource)) {
configurationElement(parser.evalNode("/mapper"));//****关键的操作藏在了这里****
configuration.addLoadedResource(resource);
bindMapperForNamespace(); //这里就是去注册mapper的地方
}
parsePendingResultMaps();
parsePendingChacheRefs();
parsePendingStatements();
}
private void configurationElement(XNode context) {
try {
String namespace = context.getStringAttribute("namespace");
builderAssistant.setCurrentNamespace(namespace);
cacheRefElement(context.evalNode("cache-ref"));
cacheElement(context.evalNode("cache"));
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
resultMapElements(context.evalNodes("/mapper/resultMap"));
sqlElement(context.evalNodes("/mapper/sql"));
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));//看到这里心里就大概明白了
} catch (Exception e) {
throw new RuntimeException("Error parsing Mapper XML. Cause: " + e, e);
}
}
继续往下看呢,代码就很长了,注意到一点,这些配置并没有关联到mapper上,而是最终直接添加到了Configuration对象的
mappedStatements
mappedStatements 是一个map,而且他的key是namespace加id。
debug了一下:
果然key就是"com.tiantao.learn.mappers.UserMapper.selectUser" namespace加上id。
同时还有一个只一个id,这两个都对应同一个对象。这么说来这个id应该是全局唯一的?!?!
记录一下调用栈
上一篇: MyBatis学习笔记——缓存