本文共 1670 字,大约阅读时间需要 5 分钟。
问题: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应该是全局唯一的?!?!
记录一下调用栈