文章目錄
- 前言
- 一、邏輯刪除的工作原理
- 二、支持的數據類型
- 三、使用方法
- 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
二、支持的數據類型
邏輯刪除字段支持所有數據類型,但推薦使用 Integer
、Boolean
或 LocalDateTime
。如果使用 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 中實現邏輯刪除功能,提高數據管理的靈活性和安全性。