解析完操作节点,生成MappedStatement以后,会注入到mappedStatements(类型为Map<String, MappedStatement>)中,会有id以及namespace.id这2种;
那么id为*Mapper.xml中操作节点的id注入的话,这种情况是何时注入的:
关键点在于StrictMap这个类,它在插入完整的id的时候,还会尝试去插入不带namespace的id这种情况(它重写了HashMap的put()方法);
附上StrictMap mappedStatements的put()方法源码:
public V put(String key, V value) {
if (containsKey(key)) {
throw new IllegalArgumentException(name + " already contains value for " + key
+ (conflictMessageProducer == null ? "" : conflictMessageProducer.apply(super.get(key), value)));
}
if (key.contains(".")) {
//这里就是把namespace.id的值给分隔,
//然后获取到id的值(即*Mapper.xml中操作节点(select/insert/update/..)的id)
final String shortKey = getShortName(key);
//不存在这个简单名称的key时候插入mappedStatements里面
if (super.get(shortKey) == null) {
super.put(shortKey, value);
} else {
//否则插入Ambiguity,后面get()方法获取到这个类的时候会报错的
super.put(shortKey, (V) new Ambiguity(shortKey));
}
}
return super.put(key, value);
}
以上就是随手写的一个小的知识点,是因为在项目中发现,传不加上namespace的id也可以找到指定的MappedStatement,自己也是找了半天也没找到原因,但使用断点发现mappedStatements中确实是存在仅仅id的key值得,不过最后还是在StrictMap当中找到源头了哈;