Files
ccdi/doc/参数配置功能/02-后端业务逻辑开发-修复报告.md
2026-02-26 10:39:12 +08:00

7.1 KiB

任务2: 后端业务逻辑开发 - 代码质量修复报告

修复日期

2026-02-26

修复概述

针对任务2(后端业务逻辑开发)中发现的严重代码质量问题进行了全面修复,确保代码的健壮性和可执行性。


已修复问题清单

问题1: 批量更新SQL语法错误 (严重)

问题描述: MySQL 默认不支持在单个 PreparedStatement 中执行分号分隔的多条SQL语句。使用 <foreach separator=";"> 会导致运行时错误。

修复文件: ccdi-project/src/main/resources/mapper/ccdi/project/CcdiModelParamMapper.xml

修复前:

<update id="batchUpdateParamValues">
    <foreach collection="list" item="item" separator=";">
        update ccdi_model_param
        set param_value = #{item.paramValue},
            update_by = #{item.updateBy},
            update_time = sysdate()
        where id = #{item.id}
    </foreach>
</update>

修复后:

<!-- 关键:只更新 param_value 字段,使用 CASE WHEN 批量更新 -->
<update id="batchUpdateParamValues">
    update ccdi_model_param
    <set>
        <trim prefix="param_value = case" suffix="end,">
            <foreach collection="list" item="item">
                when id = #{item.id} then #{item.paramValue}
            </foreach>
        </trim>
        <trim prefix="update_by = case" suffix="end,">
            <foreach collection="list" item="item">
                when id = #{item.id} then #{item.updateBy}
            </foreach>
        </trim>
        update_time = sysdate()
    </set>
    where id in
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
</update>

修复效果:

  • 使用 CASE WHEN 批量更新语法,单条SQL完成批量更新
  • 兼容 MySQL 默认配置,无需开启多语句支持
  • 性能更优,减少数据库交互次数
  • 保证事务完整性

问题2: saveParams 方法缺少空列表校验 (建议)

问题描述: Service 层未对传入的参数列表进行空值校验,可能导致空指针异常或无效的数据库操作。

修复文件: ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java

修复前:

@Override
@Transactional(rollbackFor = Exception.class)
public void saveParams(ModelParamSaveDTO saveDTO) {
    Long projectId = saveDTO.getProjectId();
    if (projectId == null) {
        projectId = 0L;
    }

    String username = SecurityUtils.getUsername();
    Date now = new Date();
    // ...
}

修复后:

@Override
@Transactional(rollbackFor = Exception.class)
public void saveParams(ModelParamSaveDTO saveDTO) {
    Long projectId = saveDTO.getProjectId();
    if (projectId == null) {
        projectId = 0L;
    }

    // 空列表校验
    if (saveDTO.getParams() == null || saveDTO.getParams().isEmpty()) {
        throw new ServiceException("参数列表不能为空");
    }

    String username = SecurityUtils.getUsername();
    Date now = new Date();
    // ...
}

修复效果:

  • 提前拦截无效请求,避免不必要的数据库查询
  • 明确的错误提示,便于前端调试
  • 提升代码健壮性

问题3: Stream 操作性能优化 (可选)

问题描述: 在循环中使用 Stream 的 filter/findFirst 查找元素,时间复杂度为 O(n²),性能较差。

修复文件: ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java

修复前:

// 准备更新列表 - 只更新 param_value 字段
List<CcdiModelParam> updateList = new ArrayList<>();
for (ModelParamSaveDTO.ParamItem item : saveDTO.getParams()) {
    CcdiModelParam existing = existingParams.stream()
        .filter(p -> p.getParamCode().equals(item.getParamCode()))
        .findFirst()
        .orElse(null);

    if (existing != null) {
        // ...
    }
}

修复后:

// 构建Map提升性能
Map<String, CcdiModelParam> existingMap = existingParams.stream()
    .collect(Collectors.toMap(CcdiModelParam::getParamCode, p -> p));

// 准备更新列表 - 只更新 param_value 字段
List<CcdiModelParam> updateList = new ArrayList<>();
for (ModelParamSaveDTO.ParamItem item : saveDTO.getParams()) {
    CcdiModelParam existing = existingMap.get(item.getParamCode());

    if (existing != null) {
        // ...
    }
}

额外添加的导入:

import java.util.Map;
import java.util.stream.Collectors;

修复效果:

  • 时间复杂度从 O(n²) 降低到 O(n)
  • 性能提升显著,尤其参数较多时
  • 代码可读性更好

验证结果

编译验证

mvn clean compile -pl ccdi-project -am

结果: BUILD SUCCESS

[INFO] Reactor Summary for ruoyi 3.9.1:
[INFO]
[INFO] ruoyi .............................................. SUCCESS [  0.127 s]
[INFO] ruoyi-common ....................................... SUCCESS [  4.148 s]
[INFO] ccdi-project ....................................... SUCCESS [  1.558 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  6.184 s

代码质量检查

规范检查

  • 所有类使用 import 导入,无全限定类名
  • Service 使用 @Resource 注入
  • Service 实现类添加 @Transactional 注解
  • 异常处理使用 ServiceException

性能检查

  • 批量更新使用 CASE WHEN 语法
  • Stream 操作优化为 Map 查找
  • 空值校验提前拦截

业务检查

  • UPDATE 只更新 param_value 字段
  • 审计字段正确设置
  • 事务管理完整

修复影响范围

修改文件

  1. CcdiModelParamMapper.xml - 批量更新SQL语法
  2. CcdiModelParamServiceImpl.java - 空列表校验 + 性能优化

影响接口

  • POST /ccdi/modelParam/save - 保存模型参数接口

兼容性

  • 向后兼容,不影响现有功能
  • 接口签名不变
  • 数据库表结构不变

测试建议

功能测试

  1. 正常场景: 批量更新参数值
  2. 边界场景: 空参数列表
  3. 异常场景: 无效的模型编码
  4. 性能测试: 大量参数更新

SQL验证

生成的SQL示例:

UPDATE ccdi_model_param
SET
    param_value = CASE
        WHEN id = 1 THEN '0.5'
        WHEN id = 2 THEN '0.3'
        WHEN id = 3 THEN '100'
    END,
    update_by = CASE
        WHEN id = 1 THEN 'admin'
        WHEN id = 2 THEN 'admin'
        WHEN id = 3 THEN 'admin'
    END,
    update_time = sysdate()
WHERE id IN (1, 2, 3)

总结

所有发现的代码质量问题均已修复完成:

  • 问题1 (严重): SQL语法错误 - 已修复
  • 问题2 (建议): 空列表校验 - 已修复
  • 问题3 (可选): 性能优化 - 已修复

修复后的代码具有:

  • 更好的健壮性
  • 更高的性能
  • 更清晰的代码结构
  • 完整的错误处理

状态: 已完成,可以进入下一阶段测试。


下一步

进入 任务3: 后端功能测试