这里报错是因为什么啊,对照网上的代码半天都没有找出来,是不是 config 和 mapper 不匹配啊?
刚开始 SqlSessionFactoryBuilder 爆红,导入包但是写代码的时候不自动提示,写完爆红
这里报错是因为什么啊,对照网上的代码半天都没有找出来,是不是 config 和 mapper 不匹配啊?
刚开始 SqlSessionFactoryBuilder 爆红,导入包但是写代码的时候不自动提示,写完爆红
【相关推荐】
private void configurationElement(XNode context) {
try {
//获取mapper标签上的namespace属性
String namespace = context.getStringAttribute("namespace");
if (namespace == null || namespace.equals("")) {
throw new BuilderException("Mapper's namespace cannot be empty");
}
//设置namespace到构建助手类中
builderAssistant.setCurrentNamespace(namespace);
//解析cache-ref标签
cacheRefElement(context.evalNode("cache-ref"));
//解析cache
cacheElement(context.evalNode("cache"));
//解析parameterMap,这种方式已经过时,不建议在使用
parameterMapElement(context.evalNodes("/mapper/parameterMap"));
//解析resultMap
resultMapElements(context.evalNodes("/mapper/resultMap"));
//解析sql片段
sqlElement(context.evalNodes("/mapper/sql"));
//解析select,insert,update,delete
buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
} catch (Exception e) {
throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
}
}
private void cacheRefElement(XNode context) {
if (context != null) {
//cacheRefMap.put(namespace, referencedNamespace);
configuration.addCacheRef(builderAssistant.getCurrentNamespace(), context.getStringAttribute("namespace"));
/* public CacheRefResolver(MapperBuilderAssistant assistant, String cacheRefNamespace) {
* this.assistant = assistant;
* this.cacheRefNamespace = cacheRefNamespace;
* }
*/
CacheRefResolver cacheRefResolver = new CacheRefResolver(builderAssistant, context.getStringAttribute("namespace"));
try {
//解析缓存引用
//(*1*)
cacheRefResolver.resolveCacheRef();
} catch (IncompleteElementException e) {
//如果解析失败,那么存放到待解析列表,等所有解析结束之后再次解析
configuration.addIncompleteCacheRef(cacheRefResolver);
}
}
}
//(*1*)
public Cache CacheRefResolver.resolveCacheRef() {
//(*2*)
return assistant.useCacheRef(cacheRefNamespace);
}
//(*2*)
public Cache org.apache.ibatis.builder.MapperBuilderAssistant.useCacheRef(String namespace) {
if (namespace == null) {
throw new BuilderException("cache-ref element requires a namespace attribute.");
}
try {
unresolvedCacheRef = true;
//从configuration的Map<String, Cache> caches中获取值
Cache cache = configuration.getCache(namespace);
if (cache == null) {
//解析失败
throw new IncompleteElementException("No cache for namespace '" + namespace + "' could be found.");
}
currentCache = cache;
unresolvedCacheRef = false;
return cache;
} catch (IllegalArgumentException e) {
throw new IncompleteElementException("No cache for namespace '" + namespace + "' could be found.", e);
}
}
private void org.apache.ibatis.builder.xml.XMLMapperBuilder.cacheElement(XNode context) throws Exception {
if (context != null) {
//获取缓存对象类型,如果没有设置,那么默认为PERPETUAL
String type = context.getStringAttribute("type", "PERPETUAL");
//解析别名
Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
//设置缓存策略:最近使用原则
String eviction = context.getStringAttribute("eviction", "LRU");
//获取LRU策略
Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
//获取刷新频率
Long flushInterval = context.getLongAttribute("flushInterval");
//获取缓存大小
Integer size = context.getIntAttribute("size");
//是否只读
boolean readWrite = !context.getBooleanAttribute("readOnly", false);
//是否阻塞
boolean blocking = context.getBooleanAttribute("blocking", false);
//获取缓存配置属性
Properties props = context.getChildrenAsProperties();
//设置缓存
//(*1*)
builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);
}
}
//(*1*)
public Cache org.apache.ibatis.builder.MapperBuilderAssistant.useNewCache(Class<? extends Cache> typeClass,
Class<? extends Cache> evictionClass,
Long flushInterval,
Integer size,
boolean readWrite,
boolean blocking,
Properties props) {
//CacheCacheBuilder(缓存建造器)
Cache cache = new CacheBuilder(currentNamespace)
//valueOrDefault在第一个参数值为null的时候会使用第二个参数,PerpetualCache为默认的缓存实现
.implementation(valueOrDefault(typeClass, PerpetualCache.class))
//设置装饰器,默认LruCache
.addDecorator(valueOrDefault(evictionClass, LruCache.class))
.clearInterval(flushInterval)
.size(size)
.readWrite(readWrite)
.blocking(blocking)
.properties(props)
.build();
//namespace -》 cache对象
configuration.addCache(cache);
//org.apache.ibatis.builder.MapperBuilderAssistant.currentCache = cache
currentCache = cache;
return cache;
}
//缓存对象的构建
public Cache org.apache.ibatis.mapping.CacheBuilder.build() {
//确保有Cache的实现类,如果没有定义,那么设置的将是PerpetualCache
setDefaultImplementations();
//寻找缓存的构造器,其构造参数为String,也就是用于传递namespace的参数
Cache cache = newBaseCacheInstance(implementation, id);
//设置属性,这个属性就是在cache标签下面设置的property标签
setCacheProperties(cache);
// issue #352, do not apply decorators to custom caches
//如果是mybatis的缓存就进行装饰,自定义的缓存只会被LoggingCache装饰
if (PerpetualCache.class.equals(cache.getClass())) {
for (Class<? extends Cache> decorator : decorators) {
cache = newCacheDecoratorInstance(decorator, cache);
//设置属性
setCacheProperties(cache);
}
//使用标准的装饰器进行装饰,比如根据是否设置了clearInterval,用ScheduledCache进行装饰
cache = setStandardDecorators(cache);
} else if (!LoggingCache.class.isAssignableFrom(cache.getClass())) {
cache = new LoggingCache(cache);
}
return cache;
}
// /mapper/parameterMap
private void org.apache.ibatis.builder.xml.XMLMapperBuilder.parameterMapElement(List<XNode> list) throws Exception {
for (XNode parameterMapNode : list) {
//解析parameterMap的id属性
String id = parameterMapNode.getStringAttribute("id");
//解析参数类型
String type = parameterMapNode.getStringAttribute("type");
//解析参数class对象
Class<?> parameterClass = resolveClass(type);
//获取parameter标签
List<XNode> parameterNodes = parameterMapNode.evalNodes("parameter");
List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
for (XNode parameterNode : parameterNodes) {
//属性名
String property = parameterNode.getStringAttribute("property");
//java类型
String javaType = parameterNode.getStringAttribute("javaType");
//jdbc类型
String jdbcType = parameterNode.getStringAttribute("jdbcType");
//resultMap,sql返回值映射,通常配置了parameterMap属性的select标签什么的,不需要再配置
//resultMap,resultType,parameterType
String resultMap = parameterNode.getStringAttribute("resultMap");
//模式,比如IN,OUT,INOUT
String mode = parameterNode.getStringAttribute("mode");
//类型处理器
String typeHandler = parameterNode.getStringAttribute("typeHandler");
//小数位
Integer numericScale = parameterNode.getIntAttribute("numericScale");
//解析参数模式ParameterMode.IN, ParameterMode.OUT,ParameterMode.INOUT
ParameterMode modeEnum = resolveParameterMode(mode);
//解析java类型
Class<?> javaTypeClass = resolveClass(javaType);
//jdbc类型
JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
@SuppressWarnings("unchecked")
//解析类型处理器
Class<? extends TypeHandler<?>> typeHandlerClass = (Class<? extends TypeHandler<?>>) resolveClass(typeHandler);
//构建ParameterMapping
//(*1*)
ParameterMapping parameterMapping = builderAssistant.buildParameterMapping(parameterClass, property, javaTypeClass, jdbcTypeEnum, resultMap, modeEnum, typeHandlerClass, numericScale);
parameterMappings.add(parameterMapping);
}
builderAssistant.addParameterMap(id, parameterClass, parameterMappings);
}
}
//(*1*)
public ParameterMapping buildParameterMapping(
Class<?> parameterType,
String property,
Class<?> javaType,
JdbcType jdbcType,
String resultMap,
ParameterMode parameterMode,
Class<? extends TypeHandler<?>> typeHandler,
Integer numericScale) {
//拼接namespace =》 namespace + "." + resultMap
resultMap = applyCurrentNamespace(resultMap, true);
// Class parameterType = parameterMapBuilder.type();
//如果javaType类型为空,那么进行解析,通常会使用MetaClass进行反射
Class<?> javaTypeClass = resolveParameterJavaType(parameterType, property, javaType, jdbcType);
//如果没有提供typeHandler,那么从typeHandler注册中获取
TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
//构建参数map
return new ParameterMapping.Builder(configuration, property, javaTypeClass)
.jdbcType(jdbcType)
.resultMapId(resultMap)
.mode(parameterMode)
.numericScale(numericScale)
.typeHandler(typeHandlerInstance)
//构建,在返回之前,如果typeHandler依然为空,会继续从typeHandler注册器中获取
//校验,eg:如果参数类型为ResultSet,那么resultMap必须存在
.build();
}
private void org.apache.ibatis.builder.xml.XMLMapperBuilder.resultMapElements(List<XNode> list) throws Exception {
for (XNode resultMapNode : list) {
try {
resultMapElement(resultMapNode);
} catch (IncompleteElementException e) {
// ignore, it will be retried
}
}
}
private ResultMap resultMapElement(XNode resultMapNode) throws Exception {
return resultMapElement(resultMapNode, Collections.<ResultMapping> emptyList());
}
//resultMap节点解析
private ResultMap resultMapElement(XNode resultMapNode, List<ResultMapping> additionalResultMappings) throws Exception {
ErrorContext.instance().activity("processing " + resultMapNode.getValueBasedIdentifier());
//获取resultMap节点属性id,如果没有那么使用默认的 resultMapNode.getValueBasedIdentifier()
String id = resultMapNode.getStringAttribute("id",
resultMapNode.getValueBasedIdentifier());
//获取返回值类型
String type = resultMapNode.getStringAttribute("type",
resultMapNode.getStringAttribute("ofType",
resultMapNode.getStringAttribute("resultType",
resultMapNode.getStringAttribute("javaType"))));
//获取继承的ResultMap配置id
String extend = resultMapNode.getStringAttribute("extends");
//是否自动映射,自动映射将采用反射的方式进行映射
Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping");
//解析成javaType
Class<?> typeClass = resolveClass(type);
//鉴别器
Discriminator discriminator = null;
List<ResultMapping> resultMappings = new ArrayList<ResultMapping>();
//添加偏好设置
resultMappings.addAll(additionalResultMappings);
List<XNode> resultChildren = resultMapNode.getChildren();
for (XNode resultChild : resultChildren) {
//解析构造器标签
if ("constructor".equals(resultChild.getName())) {
processConstructorElement(resultChild, typeClass, resultMappings);
//解析鉴别器
} else if ("discriminator".equals(resultChild.getName())) {
discriminator = processDiscriminatorElement(resultChild, typeClass, resultMappings);
} else {
List<ResultFlag> flags = new ArrayList<ResultFlag>();
//标记,标记当前属性代表主键
if ("id".equals(resultChild.getName())) {
flags.add(ResultFlag.ID);
}
//构建resultMap
resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));
}
}
ResultMapResolver resultMapResolver = new ResultMapResolver(builderAssistant, id, typeClass, extend, discriminator, resultMappings, autoMapping);
try {
//解析
return resultMapResolver.resolve();
} catch (IncompleteElementException e) {
configuration.addIncompleteResultMap(resultMapResolver);
throw e;
}
}