首页 > 其他分享 >mybatis resultMap collection聚合String

mybatis resultMap collection聚合String

时间:2022-12-19 19:00:51浏览次数:64  
标签:index cn mapper resultMap cnName collection mybatis resultMapping

背景

  • 主表index_dict_data

    img

  • 内容表index_dict_cn_name

    img

  • 期望输出数据结构:即联表之后根据indexId聚合,然后将cnName字段聚合到一个List<String>

    [
        {
            "indexId": "pageCrashNum",
            "cnNames": ["崩溃数","崩溃数"]
        },
        {
            "indexId": "pageCrashRate",
            "cnNames": ["崩溃率","崩溃率"]
        },
        {
            "indexId": "pageCrashUserNum",
            "cnNames": ["崩溃用户数","崩溃用户数"]
        }
    ]
    

配置

mapper.xml

<resultMap id="dictMap" type="com.wf.indexmetrics.IndexMetricsDictionary">
    <result column="indexId" property="indexId"/>
    <collection property="cnNames" javaType="list" ofType="java.lang.String">
        <!--虽然配置多个字段, 但是只会返回第一个, 但是聚合的时候会加入其他字段作为key-->
        <result column="cnName"/>
        <!--必须有唯一id, 否则对于相同的cnName为只保留一个-->
        <result column="cnNameId"/>
    </collection>
</resultMap>

<select id="getIndexMetricsList" resultMap="dictMap">
    SELECT
    tidd.index_id as indexId,
    tidd.dimension as dimension,
    cn.cn_name as cnName,
    cn.id as cnNameId
    FROM
    index_dict_data tidd
    LEFT JOIN index_dict_cn_name cn ON cn.index_id = tidd.index_id
    <where>
        and tidd.index_id in
        <foreach collection="indexKeys" open="(" separator="," close=")" item="item">
            #{item}
        </foreach>
    </where>
</select>

源码解析

  • org.apache.ibatis.executor.resultset.DefaultResultSetHandler#applyNestedResultMappings
private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject) {
    boolean foundValues = false;
    for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
        final String nestedResultMapId = resultMapping.getNestedResultMapId();
        if (nestedResultMapId != null && resultMapping.getResultSet() == null) {
            try {
                final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping);
                final ResultMap nestedResultMap = getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix);
                if (resultMapping.getColumnPrefix() == null) {
                    // try to fill circular reference only when columnPrefix
                    // is not specified for the nested result map (issue #215)
                    Object ancestorObject = ancestorObjects.get(nestedResultMapId);
                    if (ancestorObject != null) {
                        if (newObject) {
                            linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
                        }
                        continue;
                    }
                }
                // rowKey实际为-2048015495:-685734919:com.sf.dev.mapper.IndexMetricsDictNewMapper.mapper_resultMap[dictMap]_collection[cnNames]:cnName:崩溃率:cnNameId:1008
                final CacheKey rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
                // combinedKey实际为-381970743:-2436525477:com.sf.dev.mapper.IndexMetricsDictNewMapper.mapper_resultMap[dictMap]_collection[cnNames]:cnName:崩溃率:cnNameId:1008:-1750790558:-229051733:com.sf.dev.mapper.IndexMetricsDictNewMapper.dictMap:metricsKey:pageCrashRate:dimension:%
                final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
                // 此处通过combinedKey判断是否已存在值, 如果只有cnName而没有cnNameId就会判断已存在, 在后面的逻辑就不会再加入到List
                Object rowValue = nestedResultObjects.get(combinedKey);
                boolean knownValue = rowValue != null;
                instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory
                if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw)) {
                    rowValue = getRowValue(rsw, nestedResultMap, combinedKey, columnPrefix, rowValue);
                    if (rowValue != null && !knownValue) {
                        // 把cnName add到List
                        linkObjects(metaObject, resultMapping, rowValue);
                        foundValues = true;
                    }
                }
            } catch (SQLException e) {
                throw new ExecutorException("Error getting nested result map values for '" + resultMapping.getProperty() + "'.  Cause: " + e, e);
            }
        }
    }
    return foundValues;
}

问题

  • 起初没有配置cnNameId,保持唯一性,导致相同的cnName只保留了1个,实际应该保留2个

参考

标签:index,cn,mapper,resultMap,cnName,collection,mybatis,resultMapping
From: https://www.cnblogs.com/wftop1/p/16992857.html

相关文章

  • 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)
    摘要: 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)上篇文章《深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)》介......
  • MyBatis实现SaveOrUpdate
    这篇文章主要讲如何通过xml方式实现SaveOrUpdate,但是仍然建议在Service中实现。例子<insertid="saveOrUpdate"><selectKeykeyProperty="count"resultType="int"order......
  • mybatis的快速入门配置,以及其中的配置讲解
    Mybatis的快速入门配置,以及其中的配置理解1.快速入门案例(未使用mapper代理方式)​ (1).新建数据库,以及相关的表CREATETABLE`tb_user`(`id`int(11)NOTNULL......
  • mybatis-plus整合flowable springboot启动失败了 Correct the classpath of your appl
    问题描述:​ mybatis-plus整合flowable的时候发现springboot启动失败了异常信息如下:***************************APPLICATIONFAILEDTOSTART***********************......
  • mybatis源码分析之配置文件解析
    一、简介我们上一个篇文章已经配置好了,​​mybatis​​​配置文件和测试类。我们先分析一下​​mybatis​​​的是如何加载​​mybatis-config.xml​​文件的。Stringresou......
  • Mybatis源码分析之准备工作
    ​​Mybatis​​源码分析之准备工作一、下载源码我们从​​github​​​很慢,国内的码云可以将​​github​​项目导入到码云的自己仓库;然后就可以在码云上克隆项目,这样就方......
  • difference between collection and association mapping in mybatis 3
    Mybatis处理“一对多”的关系时,需要用到associasion元素。处理”多对一“用collection元素来实现(这两个元素在之前mapper文件中提到过)。本例子中,假设一名User可以有多个Orde......
  • Mybatis核心技术
    介绍MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为MyBatis。2013年11月迁移到Github。   MyB......
  • mybatis插入的字符串主键变成了0?
    记录一个神奇的事情,之前没这么用过。本来我插入的字符主键000000,结果插入的SQL显示0。离谱不?    直接说原因,我插入的主键本来有值,但sql写了主键赋值的操作。就......
  • MyBatis实现增删改查
    目录新建项目准备相关配置新建包和相关类增删改查实现根据id查询用户根据密码和名字查询用户给数据库增加一个用户修改用户的信息根据id删除一个用户小结模糊语句新建项目......