周五轻松修复老项目Bug,加入迭代器和SQL联合查询优化,提升代码质量!

文章讲述了如何通过迭代器优化代码,移除空数据,并利用UNIONALL进行数据合并。遇到的问题是MySQL中UNIONALL不允许跨子查询排序,解决方案是将排序部分封装到子查询中。这提高了代码的效率和可读性。
摘要由CSDN通过智能技术生成

一起来看看这些小bug

  1. 需要过滤掉页面的空数据展示,原代码中遍历列表并过滤空数据的部分,通过引入迭代器进行了优化。通过迭代器的remove方法,直接在遍历过程中移除不符合条件的数据,提高了代码的简洁性和执行效率。这个小改动让代码更加清晰、高效,伪代码:
  • 修改前:
		List<UnitVoidAnceMapperTableVo> unitVoidAnceMapperTableVos = mapper.select();
		......
		// 组装数据
        for (UnitVoidAnceMapperTableVo tableVo : unitVoidAnceMapperTableVos) {
            String unitCode = tableVo.getUnitCode();
            Map<String, BigDecimal> powerMap = unitCodePowerMap.get(unitCode);
            tableVo.setLabels(labels);
            if (powerMap==null){
                continue;
            }
            ......
        }
  • 修改后:
		List<UnitVoidAnceMapperTableVo> unitVoidAnceMapperTableVos = mapper.select();
		......
 		// 组装数据
        Iterator<UnitVoidAnceMapperTableVo> iterator = unitVoidAnceMapperTableVos.iterator();
        while (iterator.hasNext()) {
            UnitVoidAnceMapperTableVo tableVo = iterator.next();
            String unitCode = tableVo.getUnitCode();
            Map<String, BigDecimal> powerMap = unitCodePowerMap.get(unitCode);
            tableVo.setLabels(labels);
            if (powerMap == null) {
                // 去除出力为空的风电场
                iterator.remove();
                continue;
            }
            ......
        }
  1. 需要将两个查询合成一个,为了减少代码量,我选择了用 UNION ALL 来联合查询两个表的数据,因为他们的查询结果相同,伪代码:
		SELECT
            a.CODE AS unitCode,
            a.NAME AS unitName
        FROM (
                 SELECT CODE, NAME
                 FROM SPOT_WIND_SCHEME
                 WHERE SEQUENCEID = #{sequenceId}
                   AND (#{unitName} IS NULL OR NAME LIKE CONCAT('%', #{unitName}, '%'))

                 UNION ALL

                 SELECT CODE, NAME
                 FROM SPOT_PHOTOVOLTAIC_SCHEME
                 WHERE SEQUENCEID = #{sequenceId}
                   AND (#{unitName} IS NULL OR NAME LIKE CONCAT('%', #{unitName}, '%'))
             ) a
        ORDER BY a.NAME ASC

此时,页面展示的两个表的数据排序后是乱序的,我希望先展示按名字排序好的SPOT_WIND_SCHEME表的数据,再展示按名字排好序的SPOT_PHOTOVOLTAIC_SCHEME表的数据,于是我爸SQL更改为下面的,结果报错了。

    <select id="unitWindAndVoltaicTable" resultType="com.spotgoods.vo.UnitVoidAnceMapperTableVo">
        SELECT
            a.CODE AS unitCode,
            a.NAME AS unitName
        FROM (
                 SELECT CODE, NAME
                 FROM SPOT_WIND_SCHEME
                 WHERE SEQUENCEID = #{sequenceId}
                   AND (#{unitName} IS NULL OR NAME LIKE CONCAT('%', #{unitName}, '%'))
                 ORDER BY NAME ASC

                     UNION ALL

                 SELECT CODE, NAME
                 FROM SPOT_PHOTOVOLTAIC_SCHEME
                 WHERE SEQUENCEID = #{sequenceId}
                   AND (#{unitName} IS NULL OR NAME LIKE CONCAT('%', #{unitName}, '%'))
                 ORDER BY NAME ASC
             ) a
    </select>

上面的这个SQL的不对的,在使用UNION ALL时,MySQL不允许在各个子查询中使用ORDER BY。那怎么解决呢?查了些资料,原来可以这样解决。

	SELECT
        a.CODE AS unitCode,
        a.NAME AS unitName
    FROM (
        SELECT CODE, NAME
        FROM (
            SELECT CODE, NAME
            FROM SPOT_WIND_SCHEME
            WHERE SEQUENCEID = #{sequenceId}
              AND (#{unitName} IS NULL OR NAME LIKE CONCAT('%', #{unitName}, '%'))
            ORDER BY NAME ASC
        ) AS wind_scheme

        UNION ALL

        SELECT CODE, NAME
        FROM (
            SELECT CODE, NAME
            FROM SPOT_PHOTOVOLTAIC_SCHEME
            WHERE SEQUENCEID = #{sequenceId}
              AND (#{unitName} IS NULL OR NAME LIKE CONCAT('%', #{unitName}, '%'))
            ORDER BY NAME ASC
        ) AS photovoltaic_scheme
    ) a

这样,在每个表的子查询内部添加了ORDER BY 子句,并将其封装为命名的子查询(wind_scheme和photovoltaic_scheme),然后在外部查询中使用UNION ALL将它们合并。

总结

通过合并查询,减少了代码冗余,提高了代码的可维护性。学到了在使用UNION ALL时处理排序的技巧,通过在子查询内部添加ORDER BY并封装为命名的子查询解决了问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值