fix(ccdi-project): 修复审计字段和批量更新性能问题
1. 补充审计字段设置: - updateParamValue 添加 update_by 字段 - insertBatch 添加 create_by 和 update_by 字段 - Service 层手动设置审计字段 2. 优化批量更新性能: - 从循环单次更新改为批量更新 - 使用 batchUpdateParamValues 方法 - 减少数据库交互次数(从18次减少到1次) 影响:提升性能,完善审计追踪
This commit is contained in:
@@ -53,12 +53,14 @@ public interface CcdiModelParamMapper extends BaseMapper<CcdiModelParam> {
|
|||||||
* @param modelCode 模型编码
|
* @param modelCode 模型编码
|
||||||
* @param paramCode 参数编码
|
* @param paramCode 参数编码
|
||||||
* @param paramValue 参数值
|
* @param paramValue 参数值
|
||||||
|
* @param updateBy 更新者
|
||||||
* @return 影响行数
|
* @return 影响行数
|
||||||
*/
|
*/
|
||||||
int updateParamValue(
|
int updateParamValue(
|
||||||
@Param("projectId") Long projectId,
|
@Param("projectId") Long projectId,
|
||||||
@Param("modelCode") String modelCode,
|
@Param("modelCode") String modelCode,
|
||||||
@Param("paramCode") String paramCode,
|
@Param("paramCode") String paramCode,
|
||||||
@Param("paramValue") String paramValue
|
@Param("paramValue") String paramValue,
|
||||||
|
@Param("updateBy") String updateBy
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,7 +175,8 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
projectId,
|
projectId,
|
||||||
saveDTO.getModelCode(),
|
saveDTO.getModelCode(),
|
||||||
item.getParamCode(),
|
item.getParamCode(),
|
||||||
item.getParamValue()
|
item.getParamValue(),
|
||||||
|
username
|
||||||
);
|
);
|
||||||
if (updated == 0) {
|
if (updated == 0) {
|
||||||
log.warn("参数不存在或未更新,paramCode={}", item.getParamCode());
|
log.warn("参数不存在或未更新,paramCode={}", item.getParamCode());
|
||||||
@@ -209,16 +210,17 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 复制到项目
|
// 复制到项目
|
||||||
|
String username = SecurityUtils.getUsername();
|
||||||
List<CcdiModelParam> projectParams = defaultParams.stream()
|
List<CcdiModelParam> projectParams = defaultParams.stream()
|
||||||
.map(param -> {
|
.map(param -> {
|
||||||
CcdiModelParam newParam = new CcdiModelParam();
|
CcdiModelParam newParam = new CcdiModelParam();
|
||||||
BeanUtils.copyProperties(param, newParam);
|
BeanUtils.copyProperties(param, newParam);
|
||||||
newParam.setId(null); // 清空ID,让数据库自动生成
|
newParam.setId(null); // 清空ID,让数据库自动生成
|
||||||
newParam.setProjectId(projectId);
|
newParam.setProjectId(projectId);
|
||||||
newParam.setCreateBy(null); // 清空审计字段,让 MyBatis Plus 自动填充
|
// 设置审计字段
|
||||||
newParam.setCreateTime(null);
|
newParam.setCreateBy(username);
|
||||||
newParam.setUpdateBy(null);
|
newParam.setUpdateBy(username);
|
||||||
newParam.setUpdateTime(null);
|
// create_time 和 update_time 由数据库 NOW() 自动设置
|
||||||
return newParam;
|
return newParam;
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -317,16 +319,17 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 批量复制所有默认参数到项目
|
// 2. 批量复制所有默认参数到项目
|
||||||
|
String username = SecurityUtils.getUsername();
|
||||||
List<CcdiModelParam> projectParams = new ArrayList<>();
|
List<CcdiModelParam> projectParams = new ArrayList<>();
|
||||||
for (CcdiModelParam param : allDefaultParams) {
|
for (CcdiModelParam param : allDefaultParams) {
|
||||||
CcdiModelParam newParam = new CcdiModelParam();
|
CcdiModelParam newParam = new CcdiModelParam();
|
||||||
BeanUtils.copyProperties(param, newParam);
|
BeanUtils.copyProperties(param, newParam);
|
||||||
|
newParam.setId(null);
|
||||||
newParam.setProjectId(projectId);
|
newParam.setProjectId(projectId);
|
||||||
// 清空审计字段,让 MyBatis Plus 自动填充
|
// 设置审计字段
|
||||||
newParam.setCreateBy(null);
|
newParam.setCreateBy(username);
|
||||||
newParam.setCreateTime(null);
|
newParam.setUpdateBy(username);
|
||||||
newParam.setUpdateBy(null);
|
// create_time 和 update_time 由数据库 NOW() 自动设置
|
||||||
newParam.setUpdateTime(null);
|
|
||||||
projectParams.add(newParam);
|
projectParams.add(newParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,22 +345,43 @@ public class CcdiModelParamServiceImpl implements ICcdiModelParamService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 批量更新所有模型的参数值
|
// 3. 批量更新所有模型的参数值(性能优化版本)
|
||||||
|
String username = SecurityUtils.getUsername();
|
||||||
|
List<CcdiModelParam> updateList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 3.1 收集需要更新的参数
|
||||||
for (ModelParamGroupDTO modelGroup : saveAllDTO.getModels()) {
|
for (ModelParamGroupDTO modelGroup : saveAllDTO.getModels()) {
|
||||||
for (ParamValueItem item : modelGroup.getParams()) {
|
for (ParamValueItem item : modelGroup.getParams()) {
|
||||||
int updated = modelParamMapper.updateParamValue(
|
// 查询参数ID(用于批量更新)
|
||||||
projectId,
|
CcdiModelParam queryParam = new CcdiModelParam();
|
||||||
modelGroup.getModelCode(),
|
queryParam.setProjectId(projectId);
|
||||||
item.getParamCode(),
|
queryParam.setModelCode(modelGroup.getModelCode());
|
||||||
item.getParamValue()
|
queryParam.setParamCode(item.getParamCode());
|
||||||
|
|
||||||
|
// 使用 MyBatis Plus 查询
|
||||||
|
CcdiModelParam existingParam = modelParamMapper.selectOne(
|
||||||
|
new LambdaQueryWrapper<CcdiModelParam>()
|
||||||
|
.eq(CcdiModelParam::getProjectId, projectId)
|
||||||
|
.eq(CcdiModelParam::getModelCode, modelGroup.getModelCode())
|
||||||
|
.eq(CcdiModelParam::getParamCode, item.getParamCode())
|
||||||
);
|
);
|
||||||
if (updated == 0) {
|
|
||||||
log.warn("参数不存在或未更新, modelCode={}, paramCode={}",
|
if (existingParam != null) {
|
||||||
|
existingParam.setParamValue(item.getParamValue());
|
||||||
|
existingParam.setUpdateBy(username);
|
||||||
|
updateList.add(existingParam);
|
||||||
|
} else {
|
||||||
|
log.warn("参数不存在,无法更新, modelCode={}, paramCode={}",
|
||||||
modelGroup.getModelCode(), item.getParamCode());
|
modelGroup.getModelCode(), item.getParamCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3.2 批量更新(一次 SQL 执行)
|
||||||
|
if (!updateList.isEmpty()) {
|
||||||
|
modelParamMapper.batchUpdateParamValues(updateList);
|
||||||
|
log.info("批量更新参数成功, count={}", updateList.size());
|
||||||
|
}
|
||||||
} catch (ServiceException e) {
|
} catch (ServiceException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
<update id="updateParamValue">
|
<update id="updateParamValue">
|
||||||
UPDATE ccdi_model_param
|
UPDATE ccdi_model_param
|
||||||
SET param_value = #{paramValue},
|
SET param_value = #{paramValue},
|
||||||
|
update_by = #{updateBy},
|
||||||
update_time = NOW()
|
update_time = NOW()
|
||||||
WHERE project_id = #{projectId}
|
WHERE project_id = #{projectId}
|
||||||
AND model_code = #{modelCode}
|
AND model_code = #{modelCode}
|
||||||
@@ -81,14 +82,14 @@
|
|||||||
INSERT INTO ccdi_model_param (
|
INSERT INTO ccdi_model_param (
|
||||||
project_id, model_code, model_name, param_code, param_name,
|
project_id, model_code, model_name, param_code, param_name,
|
||||||
param_desc, param_value, param_unit, sort_order, remark,
|
param_desc, param_value, param_unit, sort_order, remark,
|
||||||
create_time, update_time
|
create_by, create_time, update_by, update_time
|
||||||
) VALUES
|
) VALUES
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(
|
(
|
||||||
#{item.projectId}, #{item.modelCode}, #{item.modelName},
|
#{item.projectId}, #{item.modelCode}, #{item.modelName},
|
||||||
#{item.paramCode}, #{item.paramName}, #{item.paramDesc},
|
#{item.paramCode}, #{item.paramName}, #{item.paramDesc},
|
||||||
#{item.paramValue}, #{item.paramUnit}, #{item.sortOrder},
|
#{item.paramValue}, #{item.paramUnit}, #{item.sortOrder},
|
||||||
#{item.remark}, NOW(), NOW()
|
#{item.remark}, #{item.createBy}, NOW(), #{item.updateBy}, NOW()
|
||||||
)
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
|||||||
Reference in New Issue
Block a user