0
点赞
收藏
分享

微信扫一扫

MybatisPlus使用'逻辑删除'与'唯一索引'的冲突问题解决方法

曾宝月 2024-01-03 阅读 7

问题描述

  1. MybatisPlus(以下简称mp)中默认逻辑删除值为 0删除,1未删除。这也符合正常逻辑,及时之前不用mp实现逻辑删除的时候也是这么表示的
  2. 现有一张user表,表中有name和is_delete两个字段,我们给name字段建立唯一索引
  3. 在表中插入张三后将其删除,此时表中只有一条数据 name为张三、is_delete为1
  4. 当再次插入张三时,由于name的唯一索引限制,此时报错插入失败
  5. 有人说将name和is_delete建立联合唯一索引,以上问题解决,因为is_delete值不同可以再次插入张三数据
  6. 当第二次插入的张三再次删除时,由于会产生两行 name为张三、is_delete为1的数据,由于联合唯一索引的限制,所以会删除失败

解决方法

方法一

  1. 问题的关键就是让is_delete的值不同,可以使用0代表未删除,用其他值代表已删除
  2. 这个其他值可以是UUID、时间戳、主键id
  3. 由于uuid和时间戳,有一定概率会重复(想用可以去想办法如何解决重复问题),所以我选用的是使用注解id
  4. 添加注解,或者使用全局的配置文件都可以

// 在删除标记字段上增加注解,value为未删除的值,delval为已删除的值
@TableLogic(value = "0", delval = "id")
private Integer is_delete;

  1. 查询和删除的实际执行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

如有更好解决方法,或上述有错误内容,欢迎指正,讨论交流

举报

相关推荐

0 条评论