Mybatis-Plus中逻辑删除与唯一索引冲突的解决方案

本文从本人博客搬运,原文格式更加美观,可以移步原文阅读:Mybatis-Plus中逻辑删除与唯一索引冲突的解决方案

一般情况下,对于数据表中不能重复的业务数据字段(比如身份证号,公司名称等等),我们都会为其加上唯一索引。虽然可以在业务代码中进行逻辑校验来规避重复数据被加入到数据库,但是还是建议加上唯一索引,原因如下:

  • 我们不能保证所有后端开发者都能进行严密的校验,很可能会有疏漏导致重复数据入库
  • 一般校验是否重复的方式为先查询,能查到就是重复,没查到就不重复,此时可添加。但是在高并发场景中,很可能由于并发请求过多,查询时没有重复,而插入之前被别的并发请求插入了跟你想插入的是相同的数据,导致重复数据入库。所以唯一索引可以彻底规避重复数据,是数据库中的最后一道防线

但是一旦引入逻辑删除字段后,唯一索引的功能将与其冲突。假设身份证号是唯一索引,那么删除了某个身份证号的记录,可以再次添加该身份证号的数据,而由于是逻辑删除只是将删除标记更新,并未真正删除,所以此时插入该身份证号的数据仍然会被唯一索引认为是重复数据,插入失败

我们可以按照如下步骤解决逻辑删除和唯一索引冲突的问题:

  • 将逻辑未删除值设置为0,逻辑删除值设置为null
  • 添加唯一索引时,除了业务相关字段,把逻辑删除字段也包含在唯一索引中

还是假设身份证号唯一索引的例子,这么做以后,身份证号和逻辑删除字段就成了联合唯一索引。当数据未删除时,逻辑删除字段固定为0,身份证号是否重复就决定了唯一索引的校验;当数据删除时,逻辑删除字段固定为null,由于null不会和其他字段有组合唯一键的效果,所以也就相当于解除了唯一键的约束,可以插入身份证号相同的数据

在MyBatis-Plus中,相关配置如下:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted
      logic-not-delete-value: 0
      logic-delete-value: "null"

注意:logic-delete-value的配置null一定要加引号,否则删除时会变成set 逻辑删除字段 =,等号后面没有携带值,导致SQL语法错误。加上引号以后删除的语句才会是正确的set 逻辑删除字段 = null

你可能感兴趣的:(Java,#,MyBatis,java,mybatis,逻辑删除,唯一索引,mysql)