手敲Mybatis十-结果集处理器业务逻辑
1.前言-背景介绍
上节我们处理了参数处理器,本节我们处理结果集处理器,之前我们写了一个DefaultResultSetHandler,我们把返回结果获取对象,填充值什么的写到了一起,流程没有进行解耦,并且只接收了Object的对象值类型,需要多元化,所以本节也要解决按返回类型从结果集中获取对应的结果类型值。

2.设计说明
2.1.结果映射ResultMap
我们要得到ResultType和ResultMap(本节先处理ResultType)才能知道用户最终要的是什么对象,当然定位还是要靠namespace,这时候我们需要一个类ResultMap结果映射类,内容有id(namespace+其他内容拼接)以及结果类型,还有具体结果的映射字段信息以及定义已映射字段如下第二个图片


我们看到ResultMap里有ResultMapping,这就是结果集映射里每一个字段信息(本节暂时没用上,只做定义),可以看到定义了属性,列名,java类型,jdbc类型,类型处理器
2.2 MapperBuilderAssistant助手类
为什么加这个类呢?
刚才我们说除了结果的映射构建需要namespce,其实前面章节参数也需要用到这里,而参数映射结果集都需要映射,有一些共通性,所以我们新增加一个类MapperBuilderAssistant(构建mapper助手)去帮助我们构建Mapper映射,目前参数和结果都在此类映射处理。
2.3 ResultSetHandler结果集处理
结果集处理器按字面理解就是将JDBC得到的结果集数据在此处理,最后得到返回对象结果,想要返回配置的对象而且有值,就必须解析xml中的resultType并实例化对象,并从JDBC数据集里获取属性名称,根据属性名称反射设置值并将有值的返回对象存储到结果处理器里并返回,大致的设计业务就是这样处理的。
结果包装器ResultSetWrapper
结果包装器的设计理念是想要将结果集的一些基本信息的逻辑处理到此类里,如JDBC的结果集呀,属性名称啊,jdbc类型,已映射的属性数据、未映射的属性等等处理,为结果集处理器提供数据支持。
结果上下文DefaultResultContext
结果上下文设计这个主要是每一行数据对象要存储到此类全局变量里。

结果处理器DefaultResultHandler
结果处理器设计为将每一个上下文的对象结果数据存储到List里,就可支持多个数据了。

3.UML类图
依旧和参数处理器的思路一样,分为构建处理周期以及使用周期,构建是从解析XML配置开始的,使用则是执行了数据库操作以后我们要用到处理结果的一系列流程。
大家可以看下,涉及新增的类不多,也都比较简单可以看看,其中UML中的关系MapperStatement和XmlStatementBuilder属于聚合关系,聚合关系就是比依赖要强一些的关系,整体与部分,MapperStatement就是XmlStatementBuilder的一部分协助处理映射功能的。
而ResultMapping和ResultMap就是组合关系,组合关系则要比聚合关系关联性还要强,组合则是整体与部分不分开,同根同源,同生命周期,这里呢resultMapping与ResultMap就是一个生命周期,有了ResultMapping才有ResultMap。

4.代码实现
4.1 解析构建结果映射
4.1.1 结果映射属性封装
ResultMap,结果映射,属性关于namespce和返回结果类型以及返回具体的属性信息
public class ResultMap {
private String id;
private Class<?> type;
private List<ResultMapping> resultMappings;
private Set<String> mappedColumns;
public ResultMap() {
}
public static class Builder {
private ResultMap resultMap = new ResultMap();
public Builder(Configuration configuration, String id, Class<?> type, List<ResultMapping> resultMappings) {
resultMap.id = id;
resultMap.type = type;
resultMap.resultMappings = resultMappings;
}
public ResultMap build() {
resultMap.mappedColumns = new HashSet<>();
return resultMap;
}
}
public String getId() {
return id;
}
public Class<?> getType() {
return type;
}
public List<ResultMapping> getResultMappings() {
return resultMappings;
}
public Set<String> getMappedColumns() {
return mappedColumns;
}
}
ResultMapping,具体的映射属性数据,暂时内容还没有用到,现在代码先写上
/**
* @Author df
* @Date 2023/3/28 12:38
* @Version 1.0
* 结果映射的每一个字段的信息
*/
public class ResultMapping {
private Configuration configuration;
private String property;
private String column;
private Class<?> javaType;
private JdbcType jdbcType;
private TypeHandler<?> typeHandler;
ResultMapping() {
}
public static class Builder {
private ResultMapping resultMapping = new ResultMapping();
}
}
4.1.2 绑定映射结果
MapperBuilderAssistant,协助XmlStatementBuilder去处理Mapper的映射,这样在XmlStatementBuilder就可以去掉映射这部分代码,专心处理解析,只需调用映射方法即可,其中映射返回结果的数据在setStatementResultMap方法中,最后得到的ResultMap对象存储到MappedStatement里
public class MapperBuilderAssistant extends BaseBuilder {
private String currentNamespace;
private String resource;
public MapperBuilderAssistant(Configuration configu

最低0.47元/天 解锁文章
1029

被折叠的 条评论
为什么被折叠?



