再見,物理刪除!MyBatis-Plus @TableLogic 優雅實現邏輯刪除

在開發應用程序時,我們經常會遇到需要刪除數據的場景。但直接從數據庫中物理刪除(DELETE?)數據有時并非最佳選擇。為什么呢?

  • 數據恢復: 一旦物理刪除,數據通常難以恢復,誤操作可能導致災難性后果。
  • 審計追蹤: 很多業務場景需要保留操作記錄,包括刪除記錄。
  • 數據關聯: 物理刪除可能破壞與其他表的關聯關系,導致數據不一致或需要復雜的級聯刪除策略。

這時,邏輯刪除就成了一個非常優雅的解決方案。邏輯刪除并非真的從數據庫移除數據,而是通過一個特定的字段(例如 deleted?、is_deleted?)來標記記錄的狀態,將其標記為“已刪除”。在應用程序層面,這些被標記的數據通常表現為“不存在”,但在數據庫層面,它們仍然保留著。

手動實現邏輯刪除通常意味著:

  1. 將所有的 DELETE? 操作改為 UPDATE ... SET deleted = 1 ...?。
  2. 在所有的 SELECT? 查詢中,手動添加 WHERE deleted = 0? 的條件。

這無疑會增加大量重復代碼,且容易遺漏,維護起來也相當痛苦。幸運的是,強大的 MyBatis-Plus (MP) 框架為我們提供了 @TableLogic? 注解,讓實現邏輯刪除變得極其簡單和自動化。

什么是 @TableLogic??

?@TableLogic? 是 MyBatis-Plus 提供的一個注解,用于標記實體類中代表邏輯刪除狀態的字段。一旦配置完成,MP 會在底層通過攔截器自動處理邏輯刪除相關的 SQL 轉換。

如何使用 @TableLogic??

使用 @TableLogic? 非常簡單,只需三步:

第一步:數據庫表設計

在需要支持邏輯刪除的表中,添加一個用于標記刪除狀態的字段。通常使用 TINYINT?、INT? 或 BOOLEAN? 類型。例如,我們添加一個 deleted? 字段:

ALTER TABLE `your_table_name`
ADD COLUMN `deleted` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '邏輯刪除標記(0:未刪除; 1:已刪除)';-- 為該字段添加索引通常是個好主意,特別是當已刪除數據量較大時
ALTER TABLE `your_table_name` ADD INDEX `idx_deleted` (`deleted`);

第二步:實體類配置

在對應的 Java 實體類中,添加該字段,并使用 @TableLogic? 注解標記它:

import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("your_table_name")
public class YourEntity {private Long id;private String name;// ... 其他字段@TableLogic // 標記為邏輯刪除字段private Integer deleted; // 字段類型與數據庫對應
}
  • ?@TableLogic? 注解本身就足以啟用邏輯刪除功能。

第三步:全局配置 (application.yml/properties)

雖然 @TableLogic? 注解本身已經能工作,但最佳實踐是在項目的配置文件中指定全局的“未刪除值”和“已刪除值”。這樣 MP 就知道在生成 SQL 時應該用哪些具體的值。

mybatis-plus:global-config:db-config:# 邏輯刪除字段名(如果實體類中字段名就是這個,可以省略,但推薦寫上保持清晰)# 注意:即使配置了全局字段名,實體類中仍然需要 @TableLogic 注解來 *標識* 哪個字段是邏輯刪除字段logic-delete-field: deleted# 邏輯已刪除值(默認為 1)logic-delete-value: 1# 邏輯未刪除值(默認為 0)logic-not-delete-value: 0

如果你的邏輯刪除字段名、已刪除值、未刪除值與全局配置不同,也可以在 @TableLogic? 注解中單獨指定:

// 假設用 status 字段,0表示正常,-1表示刪除
@TableLogic(value = "0", delval = "-1")
private Integer status;

但通常建議保持全局一致性。

@TableLogic? 如何工作?

配置完成后,MP 內置的 LogicSqlInnerInterceptor?(需要通過 MybatisPlusInterceptor? 注冊)就會自動生效:

  1. 對于刪除操作: 當你調用 BaseMapper? 提供的標準刪除方法時,例如:

    yourMapper.deleteById(1L);
    // 或者
    yourMapper.removeById(1L);
    

    MP 不會執行物理 DELETE?。它會自動將 SQL 轉換為:

    UPDATE your_table_name SET deleted = 1 WHERE id = 1 AND deleted = 0;
    

    它只會將當前狀態為“未刪除”(deleted = 0?) 的記錄標記為“已刪除”(deleted = 1?)。

  2. 對于查詢操作: 當你調用 BaseMapper? 提供的所有標準查詢方法時,例如:

    YourEntity entity = yourMapper.selectById(1L);
    List<YourEntity> list = yourMapper.selectList(null); // 查詢所有
    IPage<YourEntity> page = yourMapper.selectPage(pageParam, wrapper);
    // ...等等
    

    MP 會自動在這些查詢的 WHERE? 子句后面(或 WHERE? 子句內,如果沒有其他條件)追加邏輯刪除的過濾條件:

    -- selectById(1L) 可能的 SQL
    SELECT id, name, deleted /*, ...*/ FROM your_table_name WHERE id = 1 AND deleted = 0;-- selectList(null) 可能的 SQL
    SELECT id, name, deleted /*, ...*/ FROM your_table_name WHERE deleted = 0;-- selectPage(page, wrapper) 可能的 SQL (假設 wrapper 有其他條件)
    SELECT id, name, deleted /*, ...*/ FROM your_table_name WHERE name LIKE '%test%' AND deleted = 0 LIMIT ?, ?;
    

    這意味著,通過標準方法查詢時,你永遠只會得到未被邏輯刪除的數據。

如何查詢包含已刪除的數據?

這是一個常見需求,比如在后臺管理界面需要查看回收站內容,或者進行數據恢復操作。

既然 MP 的標準查詢方法會自動添加 AND deleted = 0? 的限制,那么要查詢包含已刪除的數據(甚至只查詢已刪除的數據),我們就必須繞過這個自動行為。

方法就是:使用自定義 SQL (在 Mapper XML 文件中)。

  1. 在 Mapper 接口定義方法:

    public interface YourMapper extends BaseMapper<YourEntity> {// 查詢指定 ID 的記錄,無論其刪除狀態YourEntity selectByIdIncludeDeleted(@Param("id") Long id);// 查詢所有已刪除的記錄List<YourEntity> selectDeletedList();
    }
    
  2. 在 Mapper XML 文件中編寫 SQL:

    <mapper namespace="com.yourpackage.mapper.YourMapper"><resultMap id="BaseResultMap" type="com.yourpackage.domain.YourEntity"><!-- ... 字段映射 ... --><result column="deleted" property="deleted"/></resultMap><select id="selectByIdIncludeDeleted" resultMap="BaseResultMap">SELECT id, name, deleted /*, ...*/FROM your_table_nameWHERE id = #{id}<!-- 注意:這里我們沒有寫 deleted = 0 條件,MP 也不會自動加 --></select><select id="selectDeletedList" resultMap="BaseResultMap">SELECT id, name, deleted /*, ...*/FROM your_table_nameWHERE deleted = 1 <!-- 手動指定查詢已刪除的數據 --></select>
    </mapper>
    

    關鍵在于:對于 XML 中手寫的 SQL,MP 的邏輯刪除攔截器不會去修改它,也不會自動追加 deleted? 條件。你可以完全控制查詢邏輯。

@TableLogic? 的優勢

  • 代碼簡潔: 無需在業務代碼中重復編寫 deleted = 0? 的查詢條件和 UPDATE? 式的刪除邏輯。
  • 不易出錯: 自動化處理減少了手動編碼時遺漏條件的風險。
  • 全局一致: 保證了整個應用處理邏輯刪除行為的一致性。
  • 低侵入性: 對業務代碼的侵入非常小,主要通過注解和配置完成。

注意事項

  • 性能: 如果邏輯刪除的數據量非常大,查詢性能可能會受到影響。確保在邏輯刪除字段上建立了索引。考慮定期歸檔或物理清除不再需要的已刪除數據。
  • 唯一約束: 如果表中有唯一約束,邏輯刪除可能導致問題(例如,用戶注銷賬號后,其郵箱被標記為刪除,但新用戶無法使用該郵箱注冊,因為唯一約束仍然存在)。需要根據業務場景設計合適的處理策略。

總結

MyBatis-Plus 的 @TableLogic? 為 Java 應用實現邏輯刪除提供了一個極其便捷和強大的解決方案。它通過簡單的注解和配置,將開發者從繁瑣、重復的 SQL 處理中解放出來,讓我們能更專注于業務邏輯本身。掌握并使用好 @TableLogic?,無疑能提升代碼質量和開發效率,構建更健壯、更易于維護的應用程序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903303.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903303.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903303.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

湖北理元理律師事務所:債務管理領域的平臺化創新探索

隨著中國居民負債率攀升至62%&#xff08;央行2023年數據&#xff09;&#xff0c;債務管理從個體需求演變為社會性課題。湖北理元理律師事務所通過“法律科技金融”的融合模式&#xff0c;構建了國內首個全鏈條債務管理平臺&#xff0c;其服務邏輯與行業價值值得深度剖析。 平…

【更新】LLM Interview (2)

字數溢出&#xff0c;不解釋 前文&#xff1a;llm interview (1) 文章目錄 強化學習專題1 什么是RL&#xff1f;2 RL和監督、非監督、深度學習的區別3 RL中所謂的損失函數與深度學習中的損失函數有何區別&#xff1f;4 RL歷史5 RL分類5.1 分類圖示5.2 根據智能體動作選取方式分…

高性價比手機如何挑選?

這四個關鍵點&#xff0c;助你找到心儀機~ 一、性能強者&#xff1a;游戲娛樂暢快到底 處理器相當于手機的 “大腦”&#xff0c;處理速度快、能力強&#xff0c;運行大型游戲毫無壓力。 搭配上大容量運存&#xff0c;多任務切換也能秒速完成&#xff0c;再也不怕游戲卡頓啦。…

測試—概念篇

1. 什么是需求 在多數軟件公司&#xff0c;會有兩部分需求&#xff0c;?部分是用戶需求&#xff0c;?部分是軟件需求。 1.1 用戶需求 用戶需求&#xff1a;可以簡單理解為甲方提出的需求&#xff0c;如果沒有甲方&#xff0c;那么就是終端用戶使?產品時必須要完成的任務。…

HTML5好看的水果蔬菜在線商城網站源碼系列模板7

文章目錄 1.設計來源1.1 主界面1.2 關于我們界面1.3 商城界面1.4 商品信息界面1.5 我的賬戶界面1.6 聯系我們界面 2.效果和源碼2.1 動態效果2.2 源代碼 源碼下載萬套模板&#xff0c;程序開發&#xff0c;在線開發&#xff0c;在線溝通 作者&#xff1a;xcLeigh 文章地址&#…

Atcoder Help 有關Atcoder 的介紹-1 漲分規則

AtCoder 的 Rating 計算系統基于改進的 Elo 算法&#xff0c;主要包含以下核心機制&#xff1a; 一、基礎計算公式 Rating 是「表現分(Performance)」的加權平均值減去衰減函數 f ( n ) f(n) f(n)&#xff0c;其中&#xff1a; 新用戶初始 f ( 1 ) 1200 f(1)1200 f(1)120…

設置右鍵打開VSCode

在日常的開發工作中&#xff0c;VSCode 是一款非常受歡迎的代碼編輯器。為了更加便捷地使用它&#xff0c;我們可以將 VSCode 添加到右鍵菜單中&#xff0c;這樣只需右鍵點擊文件或文件夾&#xff0c;就能快速用 VSCode 打開&#xff0c;極大地提高工作效率。下面我就來介紹一下…

python密碼學之密鑰HSM硬件抽象層(HAL)

目錄 摘要1. 項目背景與總體架構1.1 HSM 與 HAL 的必要性1.2 本項目目標1.3 模塊化設計2. 自研輕量對稱加密算法 SSC(SimpleSecureCipher)2.1 算法原理2.2 輪密鑰擴展3. HAL 接口與安全內存模擬3.1 HAL 接口定義3.2 安全內存 SecureMemory4. PyQt6 GUI 設計與功能模塊4.1 界面…

機器學習分類模型性能評估:應對類別不平衡的策略與指標

在機器學習的世界里&#xff0c;模型們就像一群努力破案的偵探&#xff0c;而數據就是它們的“犯罪現場”。今天&#xff0c;咱們的主角——一個自命不凡的分類模型&#xff0c;接到了一個看似簡單的任務&#xff1a;揪出那些患有罕見疾病的患者。這聽起來是不是很容易&#xf…

vue3代碼規范管理;基于vite和vue3、 eslint、prettier、stylelint、husky規范;git觸發eslint校驗

前言 為提高前端代碼格式化和規范開發。主要使用eslint、prettier、husky完成對git提交commit信息校驗和代碼eslint格式化校驗&#xff0c;不符合要求的代碼&#xff0c;提交不到倉庫。 參考鏈接1 參考鏈接2 文章目錄 前言一、效果圖1.git提交觸發eslint規范校驗2.版本與分支名…

GCC 內建函數匯編展開詳解

1. 引言 GNU 編譯器集合&#xff08;GCC&#xff09;是廣泛使用的開源編譯器套件&#xff0c;支持多種編程語言&#xff0c;其中 C 語言編譯器是其核心組件之一。在 C 語言編譯過程中&#xff0c;GCC 不僅處理用戶編寫的標準 C 代碼&#xff0c;還提供了一類特殊的函數——內建…

uniapp利用生命周期函數實現后臺常駐示例

在 Uniapp 中&#xff0c;利用生命周期函數實現“后臺常駐”主要是通過監聽應用的前后臺狀態變化&#xff08; onHide 和 onShow &#xff09;&#xff0c;并結合 定時器、后臺任務或狀態保持邏輯 來實現。但需注意&#xff1a; 純前端 JS 代碼無法突破系統對后臺應用的限制&am…

layui時間范圍

//時間范圍String time_range para.getString("time_range", "");if (!StrUtil.isEmpty(time_range)) {String dateArr[] time_range.split("-");if (dateArr.length 2) {para.put("start_date", dateArr[0].trim().replace("…

入門版 鴻蒙 組件導航 (Navigation)

入門版 鴻蒙 組件導航 (Navigation) 注意&#xff1a;使用 DevEco Studio 運行本案例&#xff0c;要使用模擬器&#xff0c;千萬不要用預覽器&#xff0c;預覽器看看 Navigation 布局還是可以的 效果&#xff1a;點擊首頁&#xff08;Index&#xff09;跳轉到頁面&#xff08…

VUE3:封裝一個評論回復組件

之前用React封裝的評論回復組件&#xff0c;里面有三個主要部分&#xff1a;CommentComponent作為主組件&#xff0c;CommentItem處理單個評論項&#xff0c;CommentInput負責輸入框。現在需要將這些轉換為Vue3的組件。 Vue3和React在狀態管理上有所不同&#xff0c;Vue3使用r…

制作一款打飛機游戲27:精靈編輯器UI

繼續開發我們的編輯器——Sprit Edit。我們已經創建了這個小編輯器&#xff0c;它可以顯示很多精靈&#xff08;sprites&#xff09;&#xff0c;并且我們可以遍歷所有精靈。這真的很棒&#xff0c;我們可以創建新的精靈&#xff0c;這也不錯。但是&#xff0c;唉&#xff0c;我…

k8s(9) — zookeeper集群部署(親和性、污點與容忍測試)

一、部署思路 1、前期設想 zookeeper集群至少需要運行3個pod集群才能夠正常運行&#xff0c;考慮到節點會有故障的風險這個3個pod最好分別運行在&#xff13;個不同的節點上(為了實現這一需要用到親和性和反親和性概念)&#xff0c;在部署的時候對zookeeper運行的pod打標簽加…

WXT+Vue3+sass+antd+vite搭建項目開發chrome插件

WXTVue3sassantdvite搭建項目開發chrome插件 前言一、初始化項目二、項目配置調整三、options頁面配置四、集成antd五、集成sass六、環境配置七、代碼注入 vue3&#xff1a;https://cn.vuejs.org/ axios&#xff1a;https://www.axios-http.cn/docs/api_intro antd&#xff1a;…

JSAPI2.4——正則表達式

一、語法 const str 一二三四五六七八九十 //判斷內容 const reg /二/ //判斷條件 console.log(reg.test(str)); //檢查 二、test與exec方法的區別 test方法&#xff1a;用于判斷是否符合規則的字符串&#xff0c;返回值是布爾值 exec方法&…

燃氣用戶檢修工考試精選題

燃氣用戶檢修工考試精選題&#xff1a; 我國國家標準規定民用天然氣中硫化氫含量最高允許濃度是&#xff08; &#xff09;。 A. 20mg/m B. 15mg/m C. 5mg/m D. 50mg/m 答案&#xff1a;A 城市燃氣應具有可以察覺的臭味&#xff0c;當無毒燃氣泄漏到空氣中&#xff0c;達到爆炸…