亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

解析MyBatisPlus解決邏輯刪除與唯一索引的兼容問題

 更新時間:2023年04月14日 08:34:50   作者:雨點的名字  
這篇文章主要介紹了MyBatisPlus解決邏輯刪除與唯一索引的兼容問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

需求背景

比如有張用戶表,在插入或者更新數(shù)據(jù)的時候,我們需要 用戶名稱(username),不能重復。

我們首先考慮的是給該字段創(chuàng)建唯一索引

create unique index uni_username on user(username)

似乎這樣就可以了,然而事情并沒有那么簡單。

因為我們表中的數(shù)據(jù)在刪除的時候不會真的的刪除,而是采用邏輯刪除,會有一個 deleted 字段使用0,1標識未刪除與已刪除。

當然我們可以考慮將 username + deleted 組合成一個聯(lián)合唯一索引。

create unique index uni_username_deleted on user(username,deleted)

這樣就ok了嗎?

其實會有一個新的問題,就是如果同一個用戶名如果被刪除一次。

再去刪除會發(fā)現(xiàn)系統(tǒng)報錯了,因為該條數(shù)據(jù)已經(jīng)存在了,不能在刪除了。

是不是很多時候因為邏輯刪除與唯一索引的沖突,你就不創(chuàng)建唯一索引,想著自己寫的代碼自己有信心不會出現(xiàn)臟數(shù)據(jù)的。

這么想你就太天真啦,數(shù)據(jù)庫是我們最后一道防線,這道防線都不要了嘛?

阿里巴巴手冊有關索引規(guī)范,第一條就是

【強制】業(yè)務上具有唯一特性的字段,即使是組合字段,也必須建成唯一索引。

手冊還有這么一句話:

即使在應用層做了非常完善的校驗和控制,只要沒有唯一索引,根據(jù)墨菲定律,必然有臟數(shù)據(jù)產(chǎn)生。

所以唯一索引非常有必要?。?!

那該怎么做能讓邏輯刪除與唯一索引兼容?

現(xiàn)在大家比較通用的辦法就是

我們依舊可以將 username + deleted 組合成一個聯(lián)合唯一索引,但是刪除的時候deleted不再是固定的1,而是當前的主鍵ID,也就是deleted不等于0都是刪除狀態(tài),如果刪除了那deleted值=id值

既然確立了解決方案,那就該思考怎么做?

二、MyBatisPlus邏輯刪除

MyBatisPlus是支持邏輯刪除的,如果確定在哪個字段是邏輯刪除字段,那就在該字段上添加一個注解

  /**
     * 1、刪除 0、未刪除
     */
    @TableLogic(value = "0", delval = "1")
    private Integer deleted;

這個一來操作數(shù)據(jù)是會自動變成如下:

  • 查詢時: 查詢條件會自動加上 'AND deleted = 0'
  • 刪除時: 自定添加 'UPDATE SET deleted = 1 … WHERE … AND deleted = 0'

如果你想刪除的時候不再是固定1而是id值,那么就可以這樣改

    @TableLogic(value = "0", delval = "id")
    private Integer deleted;

如果想改成全局的那么在配置文件中添加

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1 # 邏輯已刪除值(默認為 1)
      logic-not-delete-value: 0 # 邏輯未刪除值(默認為 0)

三、測試

1、用戶表

CREATE TABLE `user` (
  `id` int unsigned  AUTO_INCREMENT COMMENT '主鍵',
  `username` varchar(128)  COMMENT '用戶名',
  `phone` varchar(32)  COMMENT '手機號',
  `sex` char(1)  COMMENT '性別',
  `create_time` datetime  COMMENT '創(chuàng)建時間',
  `update_time` datetime  COMMENT '更新時間',
  `deleted` tinyint DEFAULT '0' COMMENT '1、刪除 0、未刪除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 

2、創(chuàng)建對應實體

@Data
@Accessors(chain = true)
@TableName("user")
public class UserDO implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(type = IdType.AUTO)
    private Integer id;
    /**
     * 用戶名
     */
    private String username;
    /**
     * 手機號
     */
    private String phone;
    /**
     * 性別
     */
    private String sex;
    /**
     * 創(chuàng)建時間
     */
    private LocalDateTime createTime;
    /**
     * 更新時間
     */
    private LocalDateTime updateTime;

    /**
     * 1、刪除 0、未刪除
     */
    private Integer deleted;
}

3、物理刪除測試

注意: 目前 deleted 字段是沒有添加 @TableLogic注解,同是在全局也沒有定義邏輯刪除

我們來看下刪除示例

    @Test
    public void deleteById() {
        //方式一:根據(jù)id刪除
        mapper.deleteById(10);
        //方式二:根據(jù)指定字段刪除
        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserDO::getSex, "男");
        mapper.delete(wrapper);
        //方式三:手動邏輯刪除
        UserDO userDO = new UserDO();
        userDO.setId(10);
        userDO.setDeleted(1);
        mapper.updateById(userDO);
    }

執(zhí)行結果

--方式1
DELETE FROM user WHERE id=10
--方式2
DELETE FROM user WHERE (sex = '男')
--方式3
UPDATE user SET deleted=1 WHERE id=10

我們通過結果可以看出,如果不添加邏輯刪除標識 那刪除就是物理刪除。

4、邏輯刪除測試

我們在deleted屬性字段 添加 邏輯刪除標識

 @TableLogic(value = "0", delval = "id")
 private Integer deleted;

我們再來執(zhí)行上面三個刪除,看下執(zhí)行結果

--方式1
UPDATE user SET deleted=id WHERE id=10 AND deleted=0
--方式2
UPDATE user SET deleted=id WHERE deleted=0 AND (sex = '男')
--方式3
報錯了

從執(zhí)行結果來看,方式一和方式二都從之前的物理刪除變成了邏輯刪除。

但為什么方式三會報錯呢?我們來看下報錯的結果

發(fā)現(xiàn)問題了,最終執(zhí)行的SQL竟然是:

UPDATE user  WHERE id=?  AND deleted=0

為什么是這樣,正常不應該是

UPDATE user SET deleted=1  WHERE id=?  AND deleted=0

這個就需要去看Mybatisplus到底做了什么操作,改變了我們的SQL

真相大白了

Mybatisplus在updateById更新時,如果已經(jīng)加了邏輯刪除標記,那做SQL拼接的時候,會自動過濾掉邏輯刪除的Set拼接

所以在實際開發(fā)中就非常注意,如果你的項目一開始是沒有加Mybatisplus邏輯刪除標識的,后面你在加邏輯刪除標識時,不是說加了就好了。

你還需要考慮對整體項目有沒有影響,如果之前是用updateById做邏輯刪除,那就會導致之前的刪除失敗甚至是報錯,這一點一定要注意。

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

相關文章

  • springboot攔截器不攔截靜態(tài)資源,只攔截controller的實現(xiàn)方法

    springboot攔截器不攔截靜態(tài)資源,只攔截controller的實現(xiàn)方法

    這篇文章主要介紹了springboot攔截器不攔截靜態(tài)資源,只攔截controller的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java實現(xiàn)簡易的分詞器功能

    Java實現(xiàn)簡易的分詞器功能

    搜索功能是具備數(shù)據(jù)庫功能的系統(tǒng)的一大重要特性和功能,生活中常見的搜索功能基本上都具備了分詞搜索功能.然而ES功能固然強大,但對于學生或小項目而言整合起來太費人力物力,若是寫個分詞器就會使項目錦上添花,使其不僅僅是只能單關鍵詞搜索的系統(tǒng),需要的朋友可以參考下
    2021-06-06
  • MybatisPlus中如何調(diào)用Oracle存儲過程

    MybatisPlus中如何調(diào)用Oracle存儲過程

    這篇文章主要介紹了MybatisPlus中如何調(diào)用Oracle存儲過程的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 原因分析IDEA導入Spring-kafka項目Gradle編譯失敗

    原因分析IDEA導入Spring-kafka項目Gradle編譯失敗

    這篇文章主要為大家介紹分析了IDEA導入Spring-kafka項目Gradle中編譯失敗原因及解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02
  • Myeclipse清理項目緩存的幾大方法

    Myeclipse清理項目緩存的幾大方法

    今天小編就為大家分享一篇關于Myeclipse清理項目緩存的幾大方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Gradle 創(chuàng)建Task的多種方法

    Gradle 創(chuàng)建Task的多種方法

    本文主要介紹了Gradle 創(chuàng)建Task的多種方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • JavaWeb?Listener?利用Session統(tǒng)計在線人數(shù)

    JavaWeb?Listener?利用Session統(tǒng)計在線人數(shù)

    這篇文章主要為大家介紹了JavaWeb?Listener?利用Session統(tǒng)計在線人數(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • 淺談普通for循環(huán)遍歷LinkedList弊端

    淺談普通for循環(huán)遍歷LinkedList弊端

    下面小編就為大家?guī)硪黄獪\談普通for循環(huán)遍歷LinkedList弊端。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • java中獲取json的所有key方法

    java中獲取json的所有key方法

    下面小編就為大家分享一篇java中獲取json的所有key方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Java超詳細分析講解哈希表

    Java超詳細分析講解哈希表

    哈希表是一種根據(jù)關鍵碼去尋找值的數(shù)據(jù)映射結構,該結構通過把關鍵碼映射的位置去尋找存放值的地方,說起來可能感覺有點復雜,我想我舉個例子你就會明白了,最典型的的例子就是字典
    2022-06-06

最新評論