1.前言
这一章节主要解决好几章之前留下的坑,需要根据XML配置的ReultMap进行解析映射成具体的PO供用户使用。
我们本章就来解决下在xml中配置了如下标红框的内容,怎么解析映射到具体的实体类中,如下就是将id为activityMap的resultMap怎么解析到type为Activity实体中,并将一个一个的redult的字段属性获取到以后映射到Activity的属性里,并在最终查询获取时用到了这个resultMap的结果进行属性值的反射就可以了,
下面这张图是xml与各属性之间对应的关系,我们需要根据这个关系的逻辑处理对应的映射。
首先需要有xml的resultMap标签,去定义标识id以及对应的PO实体type,然后对应的类resultMap去存储id以及type等信息,然后字段的就定义在result的column和property,主要一个是数据库字段属性,一个是实体里的属性,然后到时解析到resultMapping对应属性里,
解析完了以后执行sql语句时返回结果用的是resultMap,并把对应的resultMap类数据取出获得ResultMapping与数据库数据一一比对,匹配则进入反射并设置对应的数据库值即可。
代码还是蛮简单的,涉及的东西也不多,主要围绕着解析然后映射字段等处理来。
2.UML类图
1.主要在XmlMapperBuilder里添加解析resultMap的方法,如resultMapElement方法,解析获取resultMap的id和type,并通过buildResultMappingFromContext方法解析resultMapping的属性和列,解析完毕构建存储到resultMapping,并最终存储到resultMap中,数据都处理好了,
2.resultMap数据都处理好了后,传递到ResultMapResolver里,最终由此调用MapperBuilderAssistant助手进行resultMap的构建。
3.Sql执行完处理结果时,添加新的映射结果集处理。
3.代码实现
3.1 XMLMapperBuilder
XMLMapperBuilder类修改如下:
在configurationElement方法里新增解析resultMap操作,新增resultMapElement方法用来解析resultMap,新增buildResultMappingFromContext方法来解析resultMapping,其实都不复杂就这点业务逻辑,打个断点可以看下
public class XMLMapperBuilder extends BaseBuilder {
// 省略其他
private void configurationElement(Element element) {
// 配置namespace ,代码省略中
// 2. 解析resultMap step-13 新增
resultMapElements(element.elements("resultMap"));
// select、insert、update、delete SQL解析
}
private void resultMapElements(List<Element> list) {
for (Element element : list) {
try {
resultMapElement(element, Collections.emptyList());
} catch (Exception ignore) {
}
}
}
/**
* 解析resultMap
* <resultMap id="activityMap" type="po.Activity">
* <id column="id" property="id"/>
* <result column="activity_id" property="activityId"/>
* <result column="activity_name" property="activityName"/>
* <result column="activity_desc" property="activityDesc"/>
* <result column="create_time" property="createTime"/>
* <result column="update_time" property="updateTime"/>
* </resultMap>
*/
private void resultMapElement(Element resultMapNode, List<ResultMapping> additionalResultMappings) {
String id = resultMapNode.attributeValue("id"); // resultMap id
String type = resultMapNode.attributeValue("type"); // resultMap type
// 将resultMap的type转换Class
Class<?> typeClass = resolveClass(type);
List<ResultMapping> resultMappings = new ArrayList<>();
resultMappings.addAll(additionalResultMappings);
// resultMap所有的子result
List<Element> resultChildren = resultMapNode.elements();
for (Element resultChild : resultChildren) {
List<ResultFlag> flags = new ArrayList();
if ("id".equals(resultChild.getName())) {
flags.add(ResultFlag.ID);
}
// ResultMapping添加到集合里
resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));
}
// 创建结果映射解析器
ResultMapResolver resultMapResolver = new ResultMapResolver(builderAssistant, id, typeClass, resultMappings);
resultMapResolver.resolve();
}
/**
* <id column="id" property="id"/>
* <result column="activity_id" property="activityId"/>
*/
private ResultMapping buildResultMapp