问题描述
- MybatisPlus(以下简称mp)中默认逻辑删除值为 0删除,1未删除。这也符合正常逻辑,及时之前不用mp实现逻辑删除的时候也是这么表示的
- 现有一张user表,表中有name和is_delete两个字段,我们给name字段建立唯一索引
- 在表中插入张三后将其删除,此时表中只有一条数据 name为张三、is_delete为1
- 当再次插入张三时,由于name的唯一索引限制,此时报错插入失败
- 有人说将name和is_delete建立联合唯一索引,以上问题解决,因为is_delete值不同可以再次插入张三数据
- 当第二次插入的张三再次删除时,由于会产生两行 name为张三、is_delete为1的数据,由于联合唯一索引的限制,所以会删除失败
解决方法
方法一
- 问题的关键就是让is_delete的值不同,可以使用0代表未删除,用其他值代表已删除
- 这个其他值可以是UUID、时间戳、主键id
- 由于uuid和时间戳,有一定概率会重复(想用可以去想办法如何解决重复问题),所以我选用的是使用注解id
- 添加注解,或者使用全局的配置文件都可以
// 在删除标记字段上增加注解,value为未删除的值,delval为已删除的值
@TableLogic(value = "0", delval = "id")
private Integer is_delete;
- 查询和删除的实际执行sql如下,最终sql的值其实是直接将value和delval的值拼接在后面
# 查询实际执行sql
select * from user where is_delete = 0
# 删除实际执行sql
update user set is_delete = id where id = 1
- 注意:id的字段类型和is_delete要一致
方法二
这个方法有点别致,就是使用NULL作为已删除的标识
@TableLogic(value = "0", delval = "id")
private Integer is_delete;
该方法使用了 在mysql 的innodb引擎中,允许在唯一索引的字段中出现多个null值的特性(其他数据库可以自行验证)
所以允许数据库中出现这样的数据
name | is_delete |
张三 | NULL |
张三 | NULL |
如有更好解决方法,或上述有错误内容,欢迎指正,讨论交流