主子表编辑问题的思考

在处理业务代码时,经常遇到要编辑主子表的问题。以前遇到这个问题的时候处理方式很简单,先根据主表id删除子表数据,再把前台传入的子表信息批量入库。以学生和班级为例(下同),一个班级有多个学生,即对应数据库的班级是主表,学生是子表。为了表述方便,省略了非关键判断。代码如下:

// 更新主表信息
classAndGradeMapper.update(classAndGradeMapper)
// 根据主表id删除子表信息
String classAndGradeId = classAndGrade.getId();
studentMapper.deleteByClassAndGradeId(classAndGradeId);
// 再批量新增
studentMapper.batchInsert(insertList);

似乎是解决了问题。但这种处理方式“简单粗暴”,只适用于学生的信息“永远”不会被使用,而且无关紧要。即满足了“学生表的id永远不会被使用”这一真理。

但真实的情况真的是这么简单吗?答案并非如此。学生的考试成绩,选的课程,联系信息等等,都和学生的id有着必然的联系......

那么就必须确保编辑时子表(学生表的id)不能被轻易更改,我称之为“子表id守护”。

        // 更新主表信息
        classAndGradeMapper.update(classAndGradeMapper);
       // 主表id
        String classAndGradeId = classAndGrade.getId();
        // 1定义要批量删除的数据的集合
        List<String> deleteList = new ArrayList<>();
        // 2定义要批量新增的数据的集合
        List<Student> insertList = new ArrayList<>();
        // 3定义要批量更新的数据的集合
        List<Student> updateList = new ArrayList<>();
        // 4根据主表id,查询所有子表id
        List<String> oldStudentIds = studentMapper.findIdsByClassAndGradeId(classAndGradeId);
        // 5.获取前台传入的所有子表的id
        List<String> newStudentIds = new ArrayList<>();
        introductionStudents.forEach(e->{
            newStudentIds.add(e.getId());
        });
        // 6比较旧id和新的id是否相等,调用已经有的方法
        if (SystemUtils.listIsEquals(oldStudentIds, newStudentIds)) {
            // 6.1说明集合是相等的,并且没有null存在,这个时候全部批量更新
            studentMapper.batchUpdate(introductionStudents);
        }else{
            // 6.2
            if (newStudentIds.containsAll(oldStudentIds)) {
                // 要更新的集合真包含原集合,说明本次有新增。此时,需要更新原有的数据,新增新数据
                doAddAndUpdateList(insertList, updateList,otherParams);
            }else if(oldStudentIds.containsAll(newStudentIds)){
                // 有要删除的.此时,需要删除已经删除的数据,更新未删除的数据
                doDeleteAndUpdateList(deleteList, updateList,otherParams);
            }else{
                // 既有新增,又有删除。同时执行上述方法。
                doAddAndUpdateList(insertList, updateList,otherParams);
                doDeleteAndUpdateList(deleteList, updateList,otherParams);
            }
        }

主体方法已经完成。接下来是两个do方法,在do方法中需要分别取出哪些是新增的,哪些是编辑的,哪些是修改的。再调用数据库的批量操作。

 private void doAddAndUpdateList(List<Student> introductionStudents, List<String> oldId,
     List<Student> insertList, List<Student> updateList){
         for (Student s : introductionStudents) {
            String id = s.getId();
            if(oldId.contains(id)) {
                // 编辑
                updateList.add(s);
            }else {
                // 新增
                insertList.add(s);
            }
        }
        // 分别新增和编辑
        studentMapper.batchInsert(insertList);
        studentMapper.batchUpdate(updateList);
    }
private void doDeletAndUpdateList(List<Student> introductionStudents, 
    List<String> oldIds,List<String> newIds,List<String> deleteList, 
    List<Student> updateList) {
        
        // 遍历旧的集合
        for (String oldId : oldIds) {
            // 如果新的里有这条记录,说明是要编辑
            if (newIds.contains(oldId)) {
                // 在新的中取出要编辑的数据
                for (Student introductionStudent : introductionStudents) {
                    if(Objects.equals(oldId,introductionStudent.getId())){
                        // 编辑
                        updateList.add(introductionStudent);
                    }
                }
            } else {
                // 删除
                deleteList.add(oldId);
            }
        }
        // 分别编辑和删除
        studentMapper.deleteBatch(deleteList);
        studentMapper.batchUpdate(updateList);
    }

至此,核心代码已经完毕。因篇幅有限,没有详细列出代码,用到的时候还需要进行判空、合理值校验、事务处理等工作。当然,代码还可以进行优化的哦。

【以此记录,以备后用】

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值