【第20章】MyBatis-Plus邏輯刪除支持

文章目錄

  • 前言
  • 一、邏輯刪除的工作原理
  • 二、支持的數據類型
  • 三、使用方法
    • 1.配置全局邏輯刪除屬性
    • 2.在實體類中使用 @TableLogic 注解
  • 四、常見問題解答
  • 1. 如何處理插入操作?
    • 2. 刪除接口自動填充功能失效怎么辦?
  • 五、實戰
    • 1. 全局配置
    • 2. 添加@TableLogic
    • 3. 自動填充
    • 4. 增刪改查
    • 5. 結果
  • 總結


前言

邏輯刪除是一種優雅的數據管理策略,它通過在數據庫中標記記錄為“已刪除”而非物理刪除,來保留數據的歷史痕跡,同時確保查詢結果的整潔性。MyBatis-Plus 提供了便捷的邏輯刪除支持,使得這一策略的實施變得簡單高效。


一、邏輯刪除的工作原理

MyBatis-Plus 的邏輯刪除功能會在執行數據庫操作時自動處理邏輯刪除字段。以下是它的工作方式:

  • 插入:邏輯刪除字段的值不受限制。
  • 查找:自動添加條件,過濾掉標記為已刪除的記錄。
  • 更新:防止更新已刪除的記錄。
  • 刪除:將刪除操作轉換為更新操作,標記記錄為已刪除。

例如:

  • 刪除:update user set deleted=1 where id = 1 and deleted=0
  • 查找:select id,name,deleted from user where deleted=0

二、支持的數據類型

邏輯刪除字段支持所有數據類型,但推薦使用 IntegerBooleanLocalDateTime。如果使用 datetime 類型,可以配置邏輯未刪除值為 null,已刪除值可以使用函數如 now() 來獲取當前時間。

三、使用方法

1.配置全局邏輯刪除屬性

application.yml 中配置 MyBatis-Plus 的全局邏輯刪除屬性:

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局邏輯刪除字段名logic-delete-value: 1 # 邏輯已刪除值logic-not-delete-value: 0 # 邏輯未刪除值

2.在實體類中使用 @TableLogic 注解

在實體類中,對應數據庫表的邏輯刪除字段上添加 @TableLogic 注解:

import com.baomidou.mybatisplus.annotation.TableLogic;public class User {// 其他字段...@TableLogicprivate Integer deleted;
}

四、常見問題解答

注意事項

  • 邏輯刪除的本質:邏輯刪除的效果應等同于物理刪除,其目的是為了保留數據,實現數據價值最大化。
  • 業務需求考量:如果業務中仍需頻繁查詢這些“已刪除”的數據,應考慮是否真正需要邏輯刪除。或許,一個狀態字段來控制數據的可見性更為合適。

1. 如何處理插入操作?

  • 方法一:在數據庫中為邏輯刪除字段設置默認值。
  • 方法二:在插入數據前手動設置邏輯刪除字段的值。
  • 方法三:使用 MyBatis-Plus 的自動填充功能。

2. 刪除接口自動填充功能失效怎么辦?

  • 方法一:使用 deleteById 方法。
  • 方法二:使用 update 方法,并使用 UpdateWrapper.set(column, value)。
  • 方法三:使用 update 方法,并使用 UpdateWrapper.setSql(“column=value”)。
  • 方法四:使用 Sql 注入器注入 com.baomidou.mybatisplus.extension.injector.methods.LogicDeleteByIdWithFill 并使用(3.5.0版本已廢棄,推薦使用deleteById)。

五、實戰

1. 全局配置

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局邏輯刪除字段名logic-delete-value: 1 # 邏輯已刪除值logic-not-delete-value: 0 # 邏輯未刪除值

2. 添加@TableLogic

package org.example.springboot3.mybatisplus.model;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.example.springboot3.mybatisplus.enums.GenderEnum;
import org.example.springboot3.mybatisplus.enums.StatusEnum;
import java.time.LocalDateTime;/*** Create by zjg on 2024/6/27*/
@Getter
@Setter
@ToString
@TableName("user1")
@NoArgsConstructor
public class User {@TableId(type= IdType.AUTO)private Long id;private String name;private Integer age;private String email;private GenderEnum gender;private StatusEnum status;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.UPDATE)private LocalDateTime updateTime;@TableLogic@TableField(fill = FieldFill.INSERT)private Integer deleted;public User(String name) {this.name = name;}public User(Long id, String name) {this.id = id;this.name = name;}public User(String name, int age) {this.name=name;this.age=age;}public User(long id, String name, int age) {this.id=id;this.name=name;this.age=age;}
}

3. 自動填充

這里插入數據的時候,我們選擇前面剛學習過的自動填充

package org.example.springboot3.mybatisplus.config;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;/*** Create by zjg on 2024/7/2*/
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Value("${mybatis-plus.global-config.db-config.logic-not-delete-value}")private Integer deleted;@Overridepublic void insertFill(MetaObject metaObject) {log.info("開始插入填充...");this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());this.strictInsertFill(metaObject, "deleted", Integer.class, deleted);}@Overridepublic void updateFill(MetaObject metaObject) {log.info("開始更新填充...");this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());}
}

4. 增刪改查

package org.example.springboot3.mybatisplus.controller;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.example.springboot3.mybatisplus.model.User;
import org.example.springboot3.mybatisplus.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;/*** Create by zjg on 2024/7/3*/
@RestController
@RequestMapping("/table-logic/")
public class TableLogicController {@AutowiredUserService userService;@RequestMapping("save")public void save() {// 假設有一個 User 實體對象User user = new User();user.setName("John Doe");user.setEmail("john.doe@example.com");boolean result = userService.save(user); // 調用 save 方法if (result) {System.out.println("User saved successfully.");} else {System.out.println("Failed to save user.");}}@RequestMapping("list")public void list() {// 查詢所有用戶List<User> users = userService.list(); // 調用 list 方法for (User user : users) {System.out.println("User: " + user);}}@RequestMapping("update")public void update() {// 假設有一個 UpdateWrapper 對象,設置更新條件為 name = 'John Doe',更新字段為 emailUpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");boolean result = userService.update(updateWrapper); // 調用 update 方法if (result) {System.out.println("Record updated successfully.");} else {System.out.println("Failed to update record.");}}@RequestMapping("remove")public void remove() {// 假設有一個 QueryWrapper 對象,設置刪除條件為 name = 'John Doe'QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");boolean result = userService.remove(queryWrapper); // 調用 remove 方法if (result) {System.out.println("Record deleted successfully.");} else {System.out.println("Failed to delete record.");}}
}

5. 結果

INSERT INTO user1 ( name, email, create_time, deleted ) VALUES ( ?, ?, ?, ? )
SELECT id,name,age,email,gender,status,create_time,update_time,deleted FROM user1 WHERE deleted=0
UPDATE user1 SET email=? WHERE deleted=0 AND (name = ?)
UPDATE user1 SET deleted=1 WHERE deleted=0 AND (name = ?)

總結

回到頂部

通過以上步驟,你可以輕松地在 MyBatis-Plus 中實現邏輯刪除功能,提高數據管理的靈活性和安全性。

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

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

相關文章

高考選專業,興趣與就業前景該如何平衡?

從高考結束的那一刻開始&#xff0c;有些家長和學生就已經變得焦慮了&#xff0c;因為他們不知道成績出來的時候學生應該如何填報志愿&#xff0c;也不知道選擇什么樣的專業&#xff0c;畢竟大學里面的專業豐富多彩&#xff0c;如何選擇確實是一門學問&#xff0c;而對于學生們…

Oracle的RECYCLEBIN回收站:輕松恢復誤刪對象

目錄 Oracle的RECYCLEBIN回收站&#xff1a;輕松恢復誤刪對象一、概念二、工作原理三、使用方法1 查看回收站中的對象2 恢復回收站中的對象2.1 恢復表&#xff08;TABLE&#xff09;2.2 恢復索引&#xff08;INDEX&#xff09;2.3 恢復視圖&#xff08;VIEW&#xff09;2.4 恢復…

樂清網站建設規劃書

樂清是位于浙江省溫州市的一個縣級市&#xff0c;擁有悠久的歷史和豐富的文化底蘊。隨著互聯網的快速發展&#xff0c;網站建設成為推動樂清經濟和文化發展的重要手段。因此&#xff0c;我們認為有必要制定一個全面的樂清網站建設規劃書&#xff0c;以促進樂清的經濟繁榮和文化…

東芝 TB5128FTG 強大性能的步進電機驅動器

TB5128FTG它以高精度和高效能為設計理念&#xff0c;采用 PWM 斬波方法&#xff0c;并內置時鐘解碼器。通過先進的 BiCD 工藝制造&#xff0c;這款驅動器提供高達 50V 和 5.0A 的輸出額定值&#xff0c;成為廣泛應用場景中的強勁解決方案。 主要特性 TB5128FTG 擁有眾多確保高…

SAP PS學習筆記01 - PS概述,創建Project和WBS

本章開始學習PS&#xff08;Project System&#xff09;。 1&#xff0c;PS的概述 PS&#xff08;Project System&#xff09;是SAP企業資源規劃系統中的一個關鍵模塊&#xff0c;主要用于項目管理。 它提供了一個全面的框架來規劃、控制和執行項目&#xff0c;涵蓋了從項目啟…

【Express】自定義錯誤碼和通用返回對象

自定義錯誤碼&#xff1a; // 自定義錯誤 const {formatResponse} require("./tool");class ServiceError extends Error {/**** param message 自定義錯誤信息* param code 自定義錯誤碼*/constructor(message, code) {super(message);this.code code;}/*** 將錯…

ZeroMQ最全面試題解讀(3萬字長文)

目錄 解釋ZeroMQ是什么,它的主要用途是什么? ZeroMQ支持哪些通信模式? 描述一下ZeroMQ中的“消息”和“消息幀” 如何在C++中初始化一個ZeroMQ上下文? 在ZeroMQ中,如何創建一個套接字并將其綁定到特定端口? 解釋什么是“管道模式”(Pipe Pattern) 說明如何使用Z…

Spring的三種注入方式的優缺點分析

在 Spring 中&#xff0c;提供了三種依賴注入&#xff08;也被稱之為 "對象注入"&#xff0c;"屬性裝配"等&#xff09;的方式&#xff0c;這篇博客我們來分析一下這三種方式各有哪些優缺點。 一、屬性注入 優點 簡潔&#xff0c;使用方便。 缺點 ? 只…

競賽選題 卷積神經網絡手寫字符識別 - 深度學習

文章目錄 0 前言1 簡介2 LeNet-5 模型的介紹2.1 結構解析2.2 C1層2.3 S2層S2層和C3層連接 2.4 F6與C5層 3 寫數字識別算法模型的構建3.1 輸入層設計3.2 激活函數的選取3.3 卷積層設計3.4 降采樣層3.5 輸出層設計 4 網絡模型的總體結構5 部分實現代碼6 在線手寫識別7 最后 0 前言…

C++內存的一些知識點

一、內存分區 在C中&#xff0c;內存主要分為以下幾個區域&#xff1a; 代碼區&#xff1a;存放函數體的二進制代碼。 全局/靜態存儲區&#xff1a;存放全局變量和靜態變量&#xff0c;這些變量在程序的整個運行期間都存在。常量存儲區&#xff1a;存放常量&#xff0c;這些值…

學懂C#編程:實用方法——string字符串指定連接符拼接之 string.Join 的詳細用法

在C#中&#xff0c;string.Join 方法用于將一個字符串數組或集合中的元素連接成一個單一的字符串&#xff0c;并在每個元素之間插入指定的分隔符。這個方法非常有用&#xff0c;特別是在需要將多個字符串合并成一個字符串時。以下是 string.Join 方法的詳細用法&#xff1a; 方…

WPF UI 界面布局 魔術棒 文字筆記識別 技能提升 布局功能擴展與自定義 繼承Panel的對象,測量與排列 系列七

應用開發第一步 功能分類&#xff1a;頁面上的功能區域劃分。。。。需求分析 業務邏輯 數據流 功能模塊 UI/UX 編碼 測試 發布 功能開發與布局 不用顯式的方式設定元素的尺寸 不使用屏幕坐標來指定位置 Grid 功能最強大&#xff0c;布局最靈活的容器…

卷積神經網絡:目標檢測的黃金鑰匙

標題&#xff1a;卷積神經網絡&#xff1a;目標檢測的黃金鑰匙 卷積神經網絡&#xff08;CNN&#xff09;是深度學習中用于處理具有網格結構數據&#xff08;如圖像&#xff09;的強大工具。在目標檢測任務中&#xff0c;CNN不僅提升了檢測的準確性&#xff0c;還極大地推動了…

開發個人Go-ChatGPT--5 模型管理 (一)

開發個人Go-ChatGP–5 模型管理 (一) 背景 開發一個chatGPT的網站&#xff0c;后端服務如何實現與大模型的對話&#xff1f;是整個項目中開發困難較大的點。 如何實現上圖的聊天對話功能&#xff1f;在開發后端的時候&#xff0c;如何實現stream的響應呢&#xff1f;本文就…

Vue-Router4.0 報“Cannot read property ‘forEach‘ of undefined”

Vue-Router4.0在創建路由時 報“Cannot read property ‘forEach‘ of undefined” 解決辦法 將路由規則名稱更改為routes&#xff0c;否則報錯 import { createWebHashHistory, createRouter } from vue-router; // 創建路由規定 const routes [{path: /login,name: login,co…

Linux Docker 防火墻設置 放通 MySQL(3306) Redis(6379) 端口

Linux Docker 防火墻設置 放通 MySQL(3306) Redis(6379) 端口&#xff0c;使用firewalld 防火墻或iptables &#xff0c;因此嘗試重新啟動 firewalld 服務&#xff0c;添加防火墻規則&#xff0c;并檢查防火墻狀態。以下是詳細步驟&#xff1a; 1. 啟動 firewalld 服務 首先啟…

qt opencv 應用舉例

在Qt中使用OpenCV可以實現各種圖像處理和計算機視覺任務。以下是一些Qt與OpenCV聯合應用的具體舉例&#xff1a; 1. 圖像讀取與顯示 讀取圖像&#xff1a;使用OpenCV的imread函數可以方便地讀取各種格式的圖像文件&#xff0c;如.bmp、.jpg、.png等。這個函數返回一個Mat對象…

【Unity數據交互】Unity中使用二進制進行數據持久化

&#x1f468;?&#x1f4bb;個人主頁&#xff1a;元宇宙-秩沅 &#x1f468;?&#x1f4bb; hallo 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;?&#x1f4bb; 本文由 秩沅 原創 &#x1f468;?&#x1f4bb; 專欄交流&#x1f9e7;&…

SqlSugar分表筆記

1、使用SqlSugar的分表功能時&#xff0c;.net要使用.net core&#xff1b; 我開始使用的是.net freamwork4.72&#xff0c;程序報異常&#xff0c;沒能解決&#xff0c;換到.net core下面就正常&#xff1b; 2、SqlSugar自帶分表支持按季度、月、周、日進行分表&#x…

ArcGIS Pro SDK (七)編輯 15 版本控制選項

ArcGIS Pro SDK &#xff08;七&#xff09;編輯 15 版本控制選項 文章目錄 ArcGIS Pro SDK &#xff08;七&#xff09;編輯 15 版本控制選項獲取和設置版本控制選項 環境&#xff1a;Visual Studio 2022 .NET6 ArcGIS Pro SDK 3.0 獲取和設置版本控制選項 var vOptions A…