欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis-Plus同時(shí)使用邏輯刪除和唯一索引的問(wèn)題及解決辦法(報(bào)數(shù)據(jù)重復(fù)Duplicate entry的問(wèn)題)

 更新時(shí)間:2023年11月08日 14:53:15   作者:吳名氏.  
在開發(fā)中,我們經(jīng)常會(huì)有邏輯刪除和唯一索引同時(shí)使用的情況,但當(dāng)使用mybatis plus時(shí),如果同時(shí)使用邏輯刪除和唯一索引,會(huì)報(bào)數(shù)據(jù)重復(fù)Duplicate entry的問(wèn)題,如何解決這個(gè)問(wèn)題呢,小編給大家分享Mybatis-Plus同時(shí)使用邏輯刪除和唯一索引的問(wèn)題及解決辦法,一起看看吧

1 問(wèn)題背景

在開發(fā)中,我們經(jīng)常會(huì)有邏輯刪除和唯一索引同時(shí)使用的情況。但當(dāng)使用mybatis plus時(shí),如果同時(shí)使用邏輯刪除和唯一索引,會(huì)報(bào)數(shù)據(jù)重復(fù)Duplicate entry的問(wèn)題。

舉例來(lái)說(shuō),有表user,建立唯一索引(user_name,is_del)

CREATE TABLE `user` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id',
  `user_name` varchar(64) DEFAULT NULL COMMENT '用戶名',
  `is_del` bigint(13) DEFAULT '0' COMMENT '邏輯刪除標(biāo)識(shí)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_user_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

如果我們插入一條數(shù)據(jù)user_name='張三’的數(shù)據(jù),然后再刪除它,這時(shí)數(shù)據(jù)表中存在一條記錄,如下圖:

這時(shí)如果再插入一條’張三’,雖然之前的一條記錄已經(jīng)被邏輯刪除,但是唯一索引只建在了user_name上,所以這時(shí)會(huì)報(bào)數(shù)據(jù)重復(fù)的錯(cuò)誤

2 第一次改進(jìn)

我們把唯一索引的組合增加is_del字段

UNIQUE KEY `unique_user_name_is_del` (`user_name`,`is_del`)

這下可以再次插入’張三’這條數(shù)據(jù),插入后如下圖

但是如果第二次刪除’張三’,則還是會(huì)報(bào)錯(cuò),因?yàn)橐呀?jīng)有一條[‘張三’,1]的數(shù)據(jù),當(dāng)程序想把另一條’zhangsan’的is_del字段值為1時(shí),會(huì)因?yàn)閿?shù)據(jù)重復(fù)失??!

3 第二次改進(jìn)

此時(shí)應(yīng)該如何改進(jìn)呢,可以在user表中增加一個(gè)del_version字段,用來(lái)把已經(jīng)刪除的數(shù)據(jù)加上版本號(hào),然后將這個(gè)字段也加入唯一索引中

CREATE TABLE `user` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Id',
  `user_name` varchar(64) DEFAULT NULL COMMENT '用戶名',
  `del_version` bigint(11) DEFAULT '0' COMMENT '版本標(biāo)識(shí),用于邏輯刪除',
  `is_del` bigint(13) DEFAULT '0' COMMENT '邏輯刪除標(biāo)識(shí)',
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_user_name_is_del_del_version` (`user_name`,`is_del`,`del_version`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

未刪除的數(shù)據(jù)del_version=0,已刪除的數(shù)據(jù)del_version修改成這條記錄的id(自增id全局唯一),這樣既可以保證無(wú)法多次插入同名的數(shù)據(jù),又可以滿足數(shù)據(jù)可以多次刪除的情況
例如,我們兩次刪除同樣數(shù)據(jù)后,再重新插入,這時(shí)數(shù)據(jù)表中的數(shù)據(jù)如下:

4 代碼解決方案

我們使用mybatis plus提供的工具生成代碼,這時(shí)所有的service層接口都會(huì)繼承 IService 這個(gè)接口,這個(gè)接口有很多默認(rèn)方法,實(shí)現(xiàn)了對(duì)數(shù)據(jù)庫(kù)的操作。

我們的思路是,新建一個(gè)IBaseService接口,繼承IService接口。在這個(gè)IBaseService接口中,重寫所有和刪除相關(guān)的方法,在其中設(shè)置【del_version】=【自增id】。而原來(lái)的所有service層接口,不再繼承IService,而是繼承我們新的IBaseService。

這樣就解決了邏輯刪除和唯一索引共用的問(wèn)題,IBaseService具體代碼如下:

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.llbqhh.dao.entity.BaseDO;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * @Author wuKeFan
 * @Date 2023/11/08
 * @Description: 邏輯刪除前先更新版本號(hào)
 */
public interface IBaseService<T extends BaseDO> extends IService<T> {
    /**
     * 根據(jù) ID 刪除
     *
     * @param id 主鍵ID
     */
    @Override
    default boolean removeById(Serializable id) {
        T objDO = getBaseMapper().selectById(id);
        return beforeDelete(objDO) && SqlHelper.retBool(getBaseMapper().deleteById(id));
    }
    /**
     * 刪除對(duì)象前,先修改其版本號(hào)
     * @param objDO
     * @return
     */
    default boolean beforeDelete(T objDO) {
        if (Objects.isNull(objDO)) {
            return false;
        }
        // 邏輯刪除前先更新版本號(hào)
        objDO.setDelVersion(objDO.getId());
        return SqlHelper.retBool(getBaseMapper().updateById(objDO));
    }
    /**
     * 根據(jù) columnMap 條件,刪除記錄
     *
     * @param columnMap 表字段 map 對(duì)象
     */
    @Override
    default boolean removeByMap(Map<String, Object> columnMap) {
        throw new RuntimeException("不支持的數(shù)據(jù)庫(kù)刪除操作");
    }
    /**
     * 根據(jù) entity 條件,刪除記錄
     *
     * @param queryWrapper 實(shí)體包裝類 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    @Override
    default boolean remove(Wrapper<T> queryWrapper) {
        List<T> objDOS = getBaseMapper().selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(objDOS)) {
            objDOS.forEach(objDO -> beforeDelete(objDO));
        }
        return SqlHelper.retBool(getBaseMapper().delete(queryWrapper));
    }
    /**
     * 刪除(根據(jù)ID 批量刪除)
     *
     * @param idList 主鍵ID列表
     */
    @Override
    default boolean removeByIds(Collection<? extends Serializable> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return false;
        }
        List<T> objDOS = getBaseMapper().selectBatchIds(idList);
        if (CollectionUtils.isNotEmpty(objDOS)) {
            objDOS.forEach(objDO -> beforeDelete(objDO));
        }
        return SqlHelper.retBool(getBaseMapper().deleteBatchIds(idList));
    }
}

到此這篇關(guān)于Mybatis-Plus同時(shí)使用邏輯刪除和唯一索引的問(wèn)題及解決辦法的文章就介紹到這了,更多相關(guān)Mybatis-Plus邏輯刪除和唯一索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java如何實(shí)現(xiàn)登錄token令牌

    Java如何實(shí)現(xiàn)登錄token令牌

    這篇文章主要介紹了Java如何實(shí)現(xiàn)登錄token令牌,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 淺談Java基于Consul創(chuàng)建分布式鎖

    淺談Java基于Consul創(chuàng)建分布式鎖

    這篇文章主要介紹了淺談基于Consul創(chuàng)建分布式鎖,Consul是HashiCorp公司推出的開源工具,用于實(shí)現(xiàn)分布式系統(tǒng)的服務(wù)發(fā)現(xiàn)與配置Consul是分布式的、高可用的、可橫向擴(kuò)展的,需要的朋友可以參考下
    2023-07-07
  • java實(shí)現(xiàn)的RSA加密算法詳解

    java實(shí)現(xiàn)的RSA加密算法詳解

    這篇文章主要介紹了java實(shí)現(xiàn)的RSA加密算法,結(jié)合實(shí)例形式詳細(xì)分析了RSA加密解密的原理、java實(shí)現(xiàn)方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-06-06
  • Java JDK8新增Optional工具類講解

    Java JDK8新增Optional工具類講解

    這篇文章主要介紹了Java JDK8新增Optional工具類講解,本文通過(guò)老版和jdk8對(duì)比對(duì)null的處理方式,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • struts2的國(guó)際化實(shí)現(xiàn)網(wǎng)站整體中英文切換實(shí)例代碼

    struts2的國(guó)際化實(shí)現(xiàn)網(wǎng)站整體中英文切換實(shí)例代碼

    本篇文章主要介紹了struts2的國(guó)際化實(shí)現(xiàn)網(wǎng)站整體中英文切換實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java9新特性對(duì)HTTP2協(xié)議支持與非阻塞HTTP?API

    Java9新特性對(duì)HTTP2協(xié)議支持與非阻塞HTTP?API

    這篇文章主要為大家介紹了Java9新特性對(duì)HTTP2協(xié)議的支持與非阻塞HTTP?API,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • 幾種常見mybatis分頁(yè)的實(shí)現(xiàn)方式

    幾種常見mybatis分頁(yè)的實(shí)現(xiàn)方式

    這篇文章主要介紹了幾種常見mybatis分頁(yè)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • SpringBoot集成xxl-job實(shí)現(xiàn)超牛的定時(shí)任務(wù)的步驟詳解

    SpringBoot集成xxl-job實(shí)現(xiàn)超牛的定時(shí)任務(wù)的步驟詳解

    XXL-JOB是一個(gè)分布式任務(wù)調(diào)度平臺(tái),其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡(jiǎn)單、輕量級(jí)、易擴(kuò)展,現(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用,本文給大家介紹了SpringBoot集成xxl-job實(shí)現(xiàn)超牛的定時(shí)任務(wù),需要的朋友可以參考下
    2023-10-10
  • Java實(shí)現(xiàn)文件上傳保存

    Java實(shí)現(xiàn)文件上傳保存

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)文件上傳保存,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳解Java實(shí)現(xiàn)多種方式的http數(shù)據(jù)抓取

    詳解Java實(shí)現(xiàn)多種方式的http數(shù)據(jù)抓取

    本篇文章主要介紹了Java實(shí)現(xiàn)多種方式的http數(shù)據(jù)抓取,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。
    2016-12-12

最新評(píng)論