MyBatis-Plus 處理邏輯刪除與查詢的5種核心實(shí)現(xiàn)方法
邏輯刪除是實(shí)際開發(fā)中常用的數(shù)據(jù)保護(hù)策略,它通過在數(shù)據(jù)表中增加一個(gè)狀態(tài)字段(如is_deleted、deleted)來標(biāo)記數(shù)據(jù)是否被刪除,而不是真正從數(shù)據(jù)庫中物理刪除記錄。MyBatis-Plus 提供了完善且靈活的邏輯刪除支持,本教程將詳細(xì)介紹5種核心實(shí)現(xiàn)方法。
一、全局配置方法(推薦)
這是最常用且最便捷的方式,通過配置文件一次性設(shè)置所有邏輯刪除規(guī)則。
??核心配置代碼:??
# application.yml
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局邏輯刪除字段名
logic-delete-value: 1 # 邏輯已刪除值(默認(rèn)為1)
logic-not-delete-value: 0 # 邏輯未刪除值(默認(rèn)為0)??講解要點(diǎn):??
logic-delete-field:指定邏輯刪除字段名,所有實(shí)體類都會(huì)使用這個(gè)字段logic-delete-value:刪除時(shí)設(shè)置的值,通常為1或truelogic-not-delete-value:未刪除時(shí)的值,通常為0或false- 配置后,所有繼承
BaseMapper的Mapper都會(huì)自動(dòng)應(yīng)用此邏輯 - 刪除操作會(huì)變?yōu)閁PDATE語句,查詢會(huì)自動(dòng)添加
deleted=0條件
??優(yōu)勢(shì):?? 配置簡(jiǎn)單,一勞永逸,適合項(xiàng)目統(tǒng)一規(guī)范。
二、實(shí)體類注解配置方法
當(dāng)不同表使用不同的邏輯刪除字段或值時(shí),可以使用注解方式為每個(gè)實(shí)體類單獨(dú)配置。
??核心代碼示例:??
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
@Data
@TableName("user")
public class User {
private Long id;
private String name;
@TableLogic(value = "0", delval = "1")
private Integer deleted;
}
@Data
@TableName("product")
public class Product {
private Long id;
private String productName;
@TableLogic(value = "false", delval = "true")
private Boolean isDeleted;
}??講解要點(diǎn):??
@TableLogic注解標(biāo)注在邏輯刪除字段上value屬性:未刪除時(shí)的值,默認(rèn)為"0"delval屬性:刪除后的值,默認(rèn)為"1"- 支持多種數(shù)據(jù)類型:Integer、Boolean、String等
- 注解優(yōu)先級(jí)高于全局配置,實(shí)現(xiàn)不同表的差異化配置
??使用場(chǎng)景:?? 老項(xiàng)目改造、多數(shù)據(jù)庫表結(jié)構(gòu)不一致、特殊業(yè)務(wù)需求。
三、局部配置與自定義Wrapper方法
在某些特殊場(chǎng)景下,可能需要臨時(shí)改變邏輯刪除的行為,可以通過自定義Wrapper實(shí)現(xiàn)。
??核心代碼示例:??
// 1. 查詢時(shí)忽略邏輯刪除條件
List<User> users = userMapper.selectList(
Wrappers.<User>lambdaQuery()
.apply("deleted = 1 or deleted = 0") // 自定義條件覆蓋自動(dòng)添加的條件
);
// 2. 使用自定義SQL完全控制
@Select("SELECT * FROM user WHERE id = #{id}")
User selectByIdIgnoreLogic(@Param("id") Long id);
// 3. 鏈?zhǔn)秸{(diào)用中的特殊處理
userMapper.selectList(
new QueryWrapper<User>()
.eq("status", 1)
.and(wrapper -> wrapper.eq("deleted", 0).or().isNull("deleted"))
);??講解要點(diǎn):??
apply()方法可以添加原生SQL片段,覆蓋自動(dòng)生成的邏輯刪除條件- 自定義SQL注解(@Select、@Update等)不會(huì)自動(dòng)添加邏輯刪除條件
- 可以通過Wrapper手動(dòng)構(gòu)建包含邏輯刪除條件的復(fù)雜查詢
- 使用
or()和and()組合條件實(shí)現(xiàn)靈活控制
??適用場(chǎng)景:?? 回收站功能、數(shù)據(jù)恢復(fù)、管理員查看所有數(shù)據(jù)。
四、查詢自動(dòng)過濾的深度控制
MyBatis-Plus默認(rèn)自動(dòng)過濾已刪除數(shù)據(jù),但我們可以通過多種方式控制這一行為。
??核心配置與代碼:??
// 1. 配置類中自定義邏輯刪除處理器
@Configuration
public class MybatisPlusConfig {
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector() {
@Override
protected String getLogicDeleteSql(TableInfo tableInfo, boolean withWhere) {
// 自定義邏輯刪除SQL生成邏輯
String logicDeleteField = tableInfo.getLogicDeleteField();
return "UPDATE " + tableInfo.getTableName() +
" SET " + logicDeleteField + " = #{et." + logicDeleteField + "}" +
(withWhere ? " WHERE " + tableInfo.getKeyColumn() + "=#{et." + tableInfo.getKeyProperty() + "}" : "");
}
};
}
}
// 2. 使用@SqlParser注解控制過濾
@SqlParser(filter = true) // 過濾邏輯刪除數(shù)據(jù)
public List<User> selectActiveUsers();
@SqlParser(filter = false) // 不過濾邏輯刪除數(shù)據(jù)
public List<User> selectAllUsers();??講解要點(diǎn):??
- 可以自定義
LogicSqlInjector來改變SQL生成邏輯 @SqlParser注解的filter屬性控制是否過濾邏輯刪除數(shù)據(jù)- 支持在Service層、Mapper層或具體方法上使用
- 可以通過AOP或攔截器實(shí)現(xiàn)更復(fù)雜的過濾邏輯
五、多租戶與邏輯刪除的聯(lián)合應(yīng)用
在企業(yè)級(jí)應(yīng)用中,邏輯刪除常與多租戶數(shù)據(jù)隔離結(jié)合使用。
??核心代碼示例:??
// 1. 多租戶配置類
@Configuration
public class TenantConfig {
@Bean
public TenantLineHandler tenantLineHandler() {
return new TenantLineHandler() {
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public Expression getTenantId() {
return new LongValue(UserContext.getCurrentTenantId());
}
@Override
public boolean ignoreTable(String tableName) {
// 忽略不需要多租戶的表
return "system_config".equals(tableName);
}
};
}
}
// 2. 實(shí)體類同時(shí)支持多租戶和邏輯刪除
@Data
@TableName("order")
public class Order {
private Long id;
private String orderNo;
@TableField(fill = FieldFill.INSERT) // 自動(dòng)填充租戶ID
private Long tenantId;
@TableLogic
private Integer deleted;
}
// 3. 查詢時(shí)自動(dòng)添加租戶和邏輯刪除條件
List<Order> orders = orderMapper.selectList(
Wrappers.<Order>lambdaQuery()
.eq(Order::getStatus, 1)
// 會(huì)自動(dòng)添加:AND tenant_id = 當(dāng)前租戶ID AND deleted = 0
);??講解要點(diǎn):??
- 多租戶和邏輯刪除可以無縫結(jié)合使用
- 查詢時(shí)會(huì)自動(dòng)添加
tenant_id = ? AND deleted = 0條件 - 刪除操作會(huì)同時(shí)考慮租戶隔離
- 通過
ignoreTable方法可以排除不需要多租戶的表
注意事項(xiàng)與最佳實(shí)踐
- ??索引優(yōu)化??:邏輯刪除字段建議添加索引,特別是數(shù)據(jù)量大的表
- ??字段類型選擇??:
- 使用
tinyint或boolean類型,占用空間小 - 避免使用字符串類型,影響查詢性能
- 使用
??數(shù)據(jù)一致性??:
// 事務(wù)中處理邏輯刪除
@Transactional
public void deleteUserWithRelatedData(Long userId) {
// 刪除用戶
userMapper.deleteById(userId);
// 同時(shí)處理關(guān)聯(lián)數(shù)據(jù)
userRoleMapper.deleteByUserId(userId);
// 記錄操作日志
logService.saveDeleteLog(userId);
}- ??查詢性能??:定期歸檔已刪除數(shù)據(jù),避免表數(shù)據(jù)量過大
- ??兼容性考慮??:老數(shù)據(jù)遷移時(shí),需要批量更新邏輯刪除字段
總結(jié)
MyBatis-Plus的邏輯刪除功能設(shè)計(jì)巧妙且靈活,通過5種不同的實(shí)現(xiàn)方法,可以滿足從簡(jiǎn)單到復(fù)雜的各種業(yè)務(wù)場(chǎng)景:
- ??全局配置??:適合項(xiàng)目統(tǒng)一規(guī)范,配置簡(jiǎn)單
- ??注解配置??:支持差異化配置,靈活性強(qiáng)
- ??局部控制??:滿足特殊業(yè)務(wù)需求,可控性高
- ??深度定制??:支持SQL級(jí)別控制,擴(kuò)展性好
- ??多租戶集成??:適合企業(yè)級(jí)應(yīng)用,安全性強(qiáng)
| 方法 | 適用場(chǎng)景 | 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|---|---|
| 默認(rèn)自動(dòng)過濾 | 常規(guī)業(yè)務(wù)查詢 | 自動(dòng)生效,無需額外配置 | 無法查詢已刪除數(shù)據(jù) |
| @InterceptorIgnore | 特殊場(chǎng)景查詢已刪除 | 靈活控制單次查詢 | 需要寫注解或自定義SQL |
| 條件構(gòu)造器 | 復(fù)雜條件查詢 | 可精確控制刪除狀態(tài) | 需要手動(dòng)添加條件 |
| 自定義SQL | 完全自定義需求 | 靈活性最高 | 維護(hù)成本較高 |
| SQL注入器 | 框架擴(kuò)展需求 | 可復(fù)用性強(qiáng) | 實(shí)現(xiàn)復(fù)雜度高 |
在實(shí)際開發(fā)中,建議根據(jù)項(xiàng)目規(guī)模和復(fù)雜度選擇合適的方案。小型項(xiàng)目可以使用全局配置,大型復(fù)雜項(xiàng)目可以結(jié)合多種方式實(shí)現(xiàn)更精細(xì)的控制。邏輯刪除不僅能保護(hù)數(shù)據(jù)安全,還能為數(shù)據(jù)恢復(fù)、審計(jì)追蹤等功能提供支持,是現(xiàn)代應(yīng)用開發(fā)中不可或缺的重要特性。
到此這篇關(guān)于MyBatis-Plus 處理邏輯刪除與查詢的5種核心實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)mybatisplus邏輯刪除與查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java連接mysql數(shù)據(jù)庫代碼實(shí)例程序
這篇文章主要介紹了java連接mysql數(shù)據(jù)庫代碼實(shí)例程序,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
java向上轉(zhuǎn)型發(fā)生的時(shí)機(jī)知識(shí)點(diǎn)詳解
在本篇文章里小編給大家整理分享的是關(guān)于java向上轉(zhuǎn)型發(fā)生的時(shí)機(jī)知識(shí)點(diǎn)內(nèi)容,有興趣的讀者們可以參考下。2021-05-05
Java實(shí)現(xiàn)通訊錄管理系統(tǒng)項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)通訊錄管理系統(tǒng)項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11

