场景

置信大家工作中应该都有遇到过表单内蕴含列表数据的状况。如下图,一个出差申请单里同行人员是能够填写多行的。

首次保留是新增场景,间接insert即可。
如果容许对表单进行编辑批改,不少程序员的做法是先将数据库里的数据全副删除后,再从新insert。
例如,首次保留后数据库的数据是

id姓名
1张三
2李四

再次编辑时,即便什么都没批改,间接点击保留。因为代码里是先删除再插入,那么id会从新生成。数据库里的数据最终会变成

id姓名
3张三
4李四

明确我意思了吗?尽管界面上用户看到的还是张三李四,然而数据库里的id曾经变了。

问题

小伙伴反诘我,尽管id是变了,然而用户看到的数据没变呀,业务含意也没有变呀,业务上又不关注它的id,有什么问题呢?
真的没有问题吗?
思考下这个场景。假如这张单有2集体在同时操作,
小A把张三删除了,同时新增了王五
小B把李四删除了,同时新增了赵六
删除再插入的实现,那么最终的后果受小A和小B的解决程序影响,后者会把前者的操作给笼罩掉,数据库里的数据最终要么是小A提交的李四+王五,要么是小B提交的张三+赵六
然而在业务含意上,在小A和小B的视角里,他们会很困惑。
小A会想,我明明新增了王五,是没有保留胜利呢?还是谁把我的数据删了?
小B也会感觉委屈,我可素来没有看见过王五,更别说删除王五了。

解决

正确的形式是什么呢?
新增、编辑、删除离开解决。
我刚提出的时候,小伙伴大叫,那要从数据库里取出来一一比照,好麻烦呀。
我提了2个点。
首先,业务须要的是正确的答案。你一秒就计算出了338483893 * 95858328 = 3 ,的确很快,但后果是错的呀。你写了个简略的计划,却得不到业务想要的后果,简略又有什么意义呢?
其次,谁说没有简略的计划?

参考实现

还以小A的操作为例,假如初始数据是

id姓名
1张三
2李四

小A删除了张三,新增了王五。那么在接口传递的时候,客户端向服务器段发送的数据能够是

[  {id: 1, name: '张三', deleted: true},  {id: 2, name: '李四', deleted: false},  {id: null, name: '王五', deleted: false},]

那么服务器在收到申请后,别离解决删除、新增、删除

for(UserDto userDto: users){    if(Boolean.True.equals(userDto.deleted)){       // 删除       delete(userDto);    }else if(userDto.getId() == null){       // 新增       insert(userDto);    }else{       // 更新       update(userDto);    }}

别纠结我在for循环里操作数据库,也别纠结我间接把dto传给delete、insert等,本文的重点不在这。

后果

回到本文结尾的例子,小A和小B在各自点击保留后,看到界面上的数据从张三+李四变成了王五+赵六,然而却不会对他们造成困惑。
比方对小A来说,张三删除胜利了,王五新增胜利了。
至于隐没的李四和忽然呈现的赵六,小A一问,是你删掉李四和新增赵六了?小B答,是的。