这里也只使用一个例子来分析
1 方法bindMapperForNamespace
private void bindMapperForNamespace() {
// cn.vansky.schedule.time.menu.dao.MenuMapper
String namespace = builderAssistant.getCurrentNamespace();
if (namespace != null) {
Class<?> boundType = null;
try {
// 根据命名空间来查询相应的接口
// interface cn.vansky.schedule.time.menu.dao.MenuMapper
boundType = Resources.classForName(namespace);
} catch (ClassNotFoundException e) {
//ignore, bound type is not required
}
if (boundType != null) {
if (!configuration.hasMapper(boundType)) {
// Spring may not know the real resource name so we set a flag
// to prevent loading again this resource from the mapper interface
// look at MapperAnnotationBuilder#loadXmlResource
// 加载过的资源添加到Configuration(全局配置类)里
// 属性为Set<String> loadedResources = new HashSet<String>()
configuration.addLoadedResource("namespace:" + namespace);
// 加载的Mapper添加到Configuration(全局配置类)里
// 属性为MapperRegistry mapperRegistry = new MapperRegistry(this)
configuration.addMapper(boundType);
}
}
}
}
上面把加载过的资源文件与加载过的SQLMapper文件放入到Configuration(全局配置类)中。
MyBatis也支持注解方式,那么注释是怎么注入的呢?这个代码就在addMapper方法里面,就来看看相应的代码。
public <T> void addMapper(Class<T> type) {
if (type.isInterface()) {
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
knownMappers.put(type, new MapperProxyFactory<T>(type));
// It's important that the type is added before the parser is run
// otherwise the binding may automatically be attempted by the
// mapper parser. If the type is already known, it won't try.
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
// 注解的解析
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}
这里不在对注解方式进行分析,有兴趣的童鞋,可以自行分析一下。
上图就是Configuration(全局配置类)中添加Mapper的位置及相应的属性。