需求背景,最近接到一个运营后台-任务规则配置的需求,具体细节要求如以下prd截图,这也是“编辑”页面的效果图,如下图:
关于为何分析这个开发需求的原因,是因为通过本次开发让我搞明白了,编辑时也就是数据库的更新操作,我们常常通过updateById(也可用其他条件作为更新条件)的方式去做,这也是我的首选做法,但很遗憾这样做去实现本次需求不好控制,耗费开发时间,实现成本比较大。下面我先谈谈具体为什么?
我们常用的updateById的方式,适用于更新单表字段值的情况,这其中也包括delete操作的逻辑删除也是用这种方式实现,也就是说单表更新操作的场景,包含了“修改”、“删除”(指逻辑删除)的情况,但还缺乏了一种“增加”的场景,单表“增加”的操作往往以insert方式,所以走的是“新建”按钮操作,并非“编辑”按钮操作。
通过上边的叙述,我们回到此次prd截图上,这次的编辑针对表二就包括了“增加”(添加任务)、“修改”(编辑现有记录,即截图框中的数据值)、“删除”(删除任务)三种场景(表三通过每天次数的数值变化来控制时间输入框的数量,同理存在三种情况)。多了一种“增加”的场景,这个并不像“删除”那种实际走“修改的方式去实现,”那么我们该怎么做呢?该如何去实现呢?
方式一:采用updateById方式,副表即表二、表三的只能对已经建立的记录做编辑内容的工作,不能对表二新增任务或删除任务(截图有对应按钮控制),也不能对表三新增触发时间或删除触发时间(因为删除副表数据时我们的前端不会传给后端删除副表数据的内容即最重要的副表id过来,所以删除通过上述updateById也不成立),以下为错误代码实例:
@Override
@Transactional(rollbackFor = Exception.class)
public com.wjj.application.healthpatientapi.vo.Response updateBusinessRuleTemplateById(InsertAndUpdBizRuleTemplateDTO dto) {
BusinessRuleTemplate businessRuleTemplate = new BusinessRuleTemplate();
businessRuleTemplate.setBusinessRuleTemplateName(dto.getBusinessRuleTemplateName());
businessRuleTemplate.setId(dto.getBusinessRuleTemplateId());
//主表依然是通过主键更新的方式
businessRuleTemplateMapper.updateById(businessRuleTemplate);
List<BusinessRuleTemplateTaskDTO> bizRuleTemplateTaskDTOList = dto.getBizRuleTemplateTaskDTOList();
for (BusinessRuleTemplateTaskDTO one : bizRuleTemplateTaskDTOList) {
BusinessRuleTemplateTask businessRuleTemplateTask = new BusinessRuleTemplateTask();
BeanUtils.copyProperties(one, businessRuleTemplateTask);
businessRuleTemplateTask.setId(one.getBusinessRuleTemplateTaskId());
//表二主键
businessRuleTemplateTask.setBusinessRuleTemplateId(businessRuleTemplate.getId());
//更新表二
businessRuleTemplateTaskMapper.updateById(businessRuleTemplateTask);
List<BusinessRuleTemplateTaskItemDTO> bizRuleTemplateTaskItemDTOList = one.getBizRuleTemplateTaskItemDTOList();
for (BusinessRuleTemplateTaskItemDTO temp : bizRuleTemplateTaskItemDTOList) {
BusinessRuleTemplateTaskItem businessRuleTemplateTaskItem = new BusinessRuleTemplateTaskItem();
BeanUtils.copyProperties(temp, businessRuleTemplateTaskItem);
//表三主键
businessRuleTemplateTaskItem.setId(temp.getBusinessRuleTemplateTaskItemId());
//更新表三
businessRuleTemplateTaskItem.setBusinessRuleTemplateTaskId(businessRuleTemplateTask.getId());
businessRuleTemplateTaskItemMapper.updateById(businessRuleTemplateTaskItem);
}
}
return com.wjj.application.healthpatientapi.vo.Response.ok();
}
结论:若以这种方式实现,得加判断写逻辑把其他操作情况考虑到,而不仅仅只做更新,开发时间成本大,不建议用。
方式二:主表依然是通过主键更新的方式,副表采用先删除后新增的方式,这种为正确满足需求的方式,注意两种操作方式对子表存入主表主键方式的区别,第二种方式两个子表全部是存的主表的主键,而不是对应上级表的主键
//主表依然是通过主键更新的方式,副表采用先删除后新增的方式
@Override
@Transactional(rollbackFor = Exception.class)
public Response updateBusinessRuleTemplateById(InsertAndUpdBizRuleTemplateDTO dto) {
BusinessRuleTemplate businessRuleTemplate = new BusinessRuleTemplate();
businessRuleTemplate.setBusinessRuleTemplateName(dto.getBusinessRuleTemplateName());
businessRuleTemplate.setId(dto.getBusinessRuleTemplateId());
//主表依然是通过主键更新的方式
businessRuleTemplateMapper.updateById(businessRuleTemplate);
//先删除表二(后新增)
LambdaQueryWrapper<BusinessRuleTemplateTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(BusinessRuleTemplateTask::getBusinessRuleTemplateId, dto.getBusinessRuleTemplateId());
businessRuleTemplateTaskMapper.delete(queryWrapper);
//先删除表三(后新增)
LambdaQueryWrapper<BusinessRuleTemplateTaskItem> itemWrapper = new LambdaQueryWrapper<>();
itemWrapper.eq(BusinessRuleTemplateTaskItem::getBusinessRuleTemplateId, dto.getBusinessRuleTemplateId());
businessRuleTemplateTaskItemMapper.delete(itemWrapper);
List<BusinessRuleTemplateTaskDTO> bizRuleTemplateTaskDTOList = dto.getBizRuleTemplateTaskDTOList();
for (BusinessRuleTemplateTaskDTO one : bizRuleTemplateTaskDTOList) {
BusinessRuleTemplateTask businessRuleTemplateTask = new BusinessRuleTemplateTask();
BeanUtils.copyProperties(one, businessRuleTemplateTask);
businessRuleTemplateTask.setBusinessRuleTemplateId(businessRuleTemplate.getId());
//因上边businessRuleTemplateTaskMapper.delete操作导致逻辑删除的状态置为2也就是”删除“状态,此处需要置为”未删除“状态1
businessRuleTemplateTask.setIsDeleted(1);
//(先删除表二)后重新保存表二
businessRuleTemplateTaskMapper.insert(businessRuleTemplateTask);
List<BusinessRuleTemplateTaskItemDTO> bizRuleTemplateTaskItemDTOList = one.getBizRuleTemplateTaskItemDTOList();
for (BusinessRuleTemplateTaskItemDTO temp : bizRuleTemplateTaskItemDTOList) {
BusinessRuleTemplateTaskItem businessRuleTemplateTaskItem = new BusinessRuleTemplateTaskItem();
BeanUtils.copyProperties(temp, businessRuleTemplateTaskItem);
businessRuleTemplateTaskItem.setBusinessRuleTemplateTaskId(businessRuleTemplateTask.getId());
//因上边businessRuleTemplateTaskItemMapper.delete操作导致逻辑删除的状态置为2也就是”删除“状态,此处需要置为”未删除“状态1
businessRuleTemplateTaskItem.setIsDeleted(1);
//(先删除表三)后重新保存表三
businessRuleTemplateTaskItemMapper.insert(businessRuleTemplateTaskItem);
}
}
return Response.ok();
}