最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1 問題背景

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

舉例來說,有表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 '邏輯刪除標識',
  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ù)據(jù)表中存在一條記錄,如下圖:

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

2 第一次改進

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

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

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

但是如果第二次刪除’張三’,則還是會報錯,因為已經(jīng)有一條[‘張三’,1]的數(shù)據(jù),當程序想把另一條’zhangsan’的is_del字段值為1時,會因為數(shù)據(jù)重復失??!

3 第二次改進

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

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 '版本標識,用于邏輯刪除',
  `is_del` bigint(13) DEFAULT '0' COMMENT '邏輯刪除標識',
  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全局唯一),這樣既可以保證無法多次插入同名的數(shù)據(jù),又可以滿足數(shù)據(jù)可以多次刪除的情況
例如,我們兩次刪除同樣數(shù)據(jù)后,再重新插入,這時數(shù)據(jù)表中的數(shù)據(jù)如下:

4 代碼解決方案

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

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

這樣就解決了邏輯刪除和唯一索引共用的問題,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: 邏輯刪除前先更新版本號
 */
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));
    }
    /**
     * 刪除對象前,先修改其版本號
     * @param objDO
     * @return
     */
    default boolean beforeDelete(T objDO) {
        if (Objects.isNull(objDO)) {
            return false;
        }
        // 邏輯刪除前先更新版本號
        objDO.setDelVersion(objDO.getId());
        return SqlHelper.retBool(getBaseMapper().updateById(objDO));
    }
    /**
     * 根據(jù) columnMap 條件,刪除記錄
     *
     * @param columnMap 表字段 map 對象
     */
    @Override
    default boolean removeByMap(Map<String, Object> columnMap) {
        throw new RuntimeException("不支持的數(shù)據(jù)庫刪除操作");
    }
    /**
     * 根據(jù) entity 條件,刪除記錄
     *
     * @param queryWrapper 實體包裝類 {@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));
    }
}

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

相關文章

  • Spring覆蓋容器中Bean的注解如何實現(xiàn)@OverrideBean

    Spring覆蓋容器中Bean的注解如何實現(xiàn)@OverrideBean

    文章介紹了在項目開發(fā)中如何通過偷梁換柱的方式重寫Spring容器中的內(nèi)置Bean,并指出了需要注意的兩點:1. 對應的Bean應基于接口注入;2. 如果不是基于接口注入,可以使用同包名同類名的方式重寫(可能存在潛在問題,不推薦),文章還強調(diào)了“基于接口編程”的好處
    2025-01-01
  • Java壓縮和解壓縮ZIP文件實戰(zhàn)案例

    Java壓縮和解壓縮ZIP文件實戰(zhàn)案例

    這篇文章主要給大家介紹了關于Java壓縮和解壓縮ZIP文件的相關資料,ZIP是一種較為常見的壓縮形式,最近項目中遇到了再Java中壓縮和解壓縮zip文件的需求,特此分享給大家,需要的朋友可以參考下
    2023-07-07
  • MyBatis配置與CRUD超詳細講解

    MyBatis配置與CRUD超詳細講解

    這篇文章主要介紹了MyBatis配置與CRUD,CRUD是指在做計算處理時的增加(Create)、讀取(Read)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫。CRUD主要被用在描述軟件系統(tǒng)中數(shù)據(jù)庫或者持久層的基本操作功能
    2023-02-02
  • java使用OpenCV從視頻文件中獲取幀

    java使用OpenCV從視頻文件中獲取幀

    這篇文章主要為大家詳細介紹了java使用OpenCV從視頻文件中獲取幀,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java泛型T,E,K,V,N,?與Object區(qū)別和含義

    Java泛型T,E,K,V,N,?與Object區(qū)別和含義

    Java?泛型(generics)是?JDK?5?中引入的一個新特性,?泛型提供了編譯時類型安全檢測機制,該機制允許程序員在編譯時檢測到非法的類型。本文將詳細講講Java泛型T、E、K、V、N、?和Object區(qū)別和含義,需要發(fā)可以參考一下
    2022-03-03
  • Java實現(xiàn)定時任務的方法詳解

    Java實現(xiàn)定時任務的方法詳解

    大家都用過鬧鐘,鬧鐘可以說是一種定時任務。那么,在?Java?中,如何實現(xiàn)這樣的功能呢?即如何實現(xiàn)定時任務呢?本文就來詳細和大家聊聊
    2022-10-10
  • java如何實現(xiàn)postman中用x-www-form-urlencoded參數(shù)的請求

    java如何實現(xiàn)postman中用x-www-form-urlencoded參數(shù)的請求

    在Java開發(fā)中,模擬Postman發(fā)送x-www-form-urlencoded類型的請求是一個常見需求,本文主要介紹了如何在Java中實現(xiàn)這一功能,首先,需要通過導入http-client包來創(chuàng)建HTTP客戶端,接著,利用該客戶端發(fā)送Post請求
    2024-09-09
  • Java中文件管理系統(tǒng)FastDFS詳解

    Java中文件管理系統(tǒng)FastDFS詳解

    這篇文章主要介紹了Java中文件管理系統(tǒng)FastDFS詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • springboot遠程執(zhí)行服務器指令

    springboot遠程執(zhí)行服務器指令

    這篇文章主要介紹了springboot遠程執(zhí)行服務器指令,本例是java遠程連接到服務器,去抓取查詢kubesphere中的etcd日志,并返回,需要的朋友可以參考下
    2023-09-09
  • 初識Java環(huán)境變量配置及IDEA

    初識Java環(huán)境變量配置及IDEA

    這篇文章主要介紹了Java環(huán)境變量配置及IDEA,本文通過圖文實例相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03

最新評論

巢湖市| 通渭县| 麻城市| 耒阳市| 永仁县| 扎囊县| 乌什县| 邻水| 洛浦县| 临湘市| 保定市| 深水埗区| 行唐县| 三台县| 乌鲁木齐县| 巴彦淖尔市| 南丹县| 三台县| 钟祥市| 德格县| 左贡县| 阳山县| 抚州市| 江门市| 西安市| 环江| 清苑县| 黔西县| 广西| 板桥市| 莱西市| 宁乡县| 青浦区| 县级市| 大足县| 留坝县| 沽源县| 双柏县| 比如县| 习水县| 玉树县|