Mybatis-Plus 自動(dòng)填充失效問(wèn)題解決
確認(rèn)版本
首先確認(rèn)你的項(xiàng)目中使用的 mybatis-plus 版本是 3.3.0 以下還是 3.3.0 以上(包含 3.3.0),在低版本和高版本中重寫 MetaObjectHandler 方法的 insertFill 和 updateFill 的寫法是不同的,比如下面示例:
@Bean
public MetaObjectHandler metaObjectHandler(){
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createdDate", new Date(), metaObject);
this.setFieldValByName("updatedDate", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updatedDate", new Date(), metaObject);
}
};
}
這是使用 MyBatis-Plus 早期版本(在 3.3.0 之前)的自定義 MetaObjectHandler 實(shí)現(xiàn)。它使用 setFieldValByName 方法來(lái)設(shè)置 createdDate 和 updatedDate 字段的值。這種方法使用的是 java.util.Date 類型。
@Bean
public MetaObjectHandler metaObjectHandler(){
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createdDate", Date.class, new Date());
this.strictInsertFill(metaObject, "updatedDate", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updatedDate", LocalDateTime.class, LocalDateTime.now());
}
};
}
這是使用 MyBatis-Plus 3.3.0 及以上版本中引入的更高級(jí)的填充策略。它使用 strictInsertFill 和 strictUpdateFill 方法,這些方法更加類型安全,也提供了更靈活的填充選項(xiàng)。此版本推薦使用 java.time.LocalDateTime 類型,這符合 Java 8 及更高版本中引入的時(shí)間 API,提供了更好的日期和時(shí)間處理能力。
詳細(xì)對(duì)比:
類型安全性:
第二種寫法中,strictInsertFill 和 strictUpdateFill 方法允許你指定目標(biāo)字段的數(shù)據(jù)類型(例如 LocalDateTime.class),從而避免了類型轉(zhuǎn)換錯(cuò)誤。
第一種寫法中,setFieldValByName 方法需要你自己確保字段類型和賦值類型的一致性。
默認(rèn)值提供方式:
第二種寫法中,你可以直接傳遞一個(gè) LocalDateTime.now() 表達(dá)式,或者使用 lambda 表達(dá)式 () -> LocalDateTime.now() 來(lái)提供一個(gè)延遲執(zhí)行的默認(rèn)值。這在某些情況下可能更有用,比如當(dāng)你的默認(rèn)值依賴于一些業(yè)務(wù)邏輯時(shí)。
第一種寫法直接使用 new Date() 創(chuàng)建日期實(shí)例,沒(méi)有提供延遲執(zhí)行的機(jī)制。
兼容性和 bug 修復(fù):
第二種寫法是 MyBatis-Plus 推薦的最新實(shí)踐,通常意味著它有更好的兼容性和已知問(wèn)題的修復(fù)。
第一種寫法可能在新版本中不再得到支持,或存在未解決的 bug,例如 fillStrategy 方法在 3.3.0 版本中有 bug。
檢查配置
首先是引入高版本的 pom 依賴:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.0</version> </dependency>
編寫mybatis-plus的配置類
/**
* MyBatis-Plus配置類
*/
@MapperScan("com.demo.mapper") // 定義項(xiàng)目中的 mapper 路徑
@Configuration
public class MybatisPlusConfig {
/**
* mybatis-plus 自動(dòng)填充配置
*/
@Bean
public MetaObjectHandler metaObjectHandler(){
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
/**
* 第一個(gè)參數(shù) metaObject 這里面包含了你傳入的實(shí)體類
* 第二個(gè)參數(shù)要和實(shí)體類中的屬性名保持一致
* 第三個(gè)參數(shù)要跟實(shí)體類中的屬性類型保持一致
* 第四個(gè)參數(shù)是你設(shè)置的填充默認(rèn)值
*/
this.strictInsertFill(metaObject, "createdDate", Date.class, new Date());
this.strictInsertFill(metaObject, "updatedDate", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updatedDate", Date.class, new Date());
}
};
}
}
在實(shí)體類中,你需要使用 @TableField 注解來(lái)標(biāo)記哪些字段需要自動(dòng)填充,并指定填充的策略。
public class User {
@TableField(fill = FieldFill.INSERT)
private String createTime;
@TableField(fill = FieldFill.UPDATE)
private String updateTime;
// 其他字段...
}
delete 和 update 方法的區(qū)別
在 MyBatis-Plus 中,`delete` 方法和 `update` 方法的行為差異主要源于它們對(duì) `MetaObjectHandler` 中定義的自動(dòng)填充邏輯的調(diào)用時(shí)機(jī)和方式的不同。
對(duì)于 update方法:
當(dāng)你使用 update 方法時(shí),MyBatis-Plus 會(huì)調(diào)用 MetaObjectHandler 的 updateFill 方法。這是因?yàn)?nbsp;update 方法本質(zhì)上是一個(gè)更新操作,它會(huì)觸發(fā)自動(dòng)填充邏輯,尤其是那些被標(biāo)記為 FieldFill.UPDATE 或 FieldFill.INSERT_UPDATE 的字段。
對(duì)于 delete 方法:
當(dāng)使用 delete 方法時(shí),情況就有所不同了。默認(rèn)情況下,delete 方法不會(huì)觸發(fā) MetaObjectHandler 的 updateFill 方法,即使你正在使用邏輯刪除(即,delete 方法實(shí)際上執(zhí)行的是一個(gè) UPDATE 語(yǔ)句來(lái)修改一個(gè)邏輯刪除標(biāo)志)。這是因?yàn)樵?MyBatis-Plus 的設(shè)計(jì)中,delete 方法的目的就是刪除記錄,無(wú)論是物理刪除還是邏輯刪除,它都不會(huì)觸發(fā)更新字段的自動(dòng)填充邏輯。
然而,當(dāng)你在實(shí)體類中使用了 @TableLogic 注解并配置了邏輯刪除,MyBatis-Plus 的 delete 方法會(huì)執(zhí)行一個(gè) UPDATE 語(yǔ)句來(lái)改變邏輯刪除字段的值,但它不會(huì)執(zhí)行 updateFill 方法來(lái)更新其他字段,如 updatedDate。這是 MyBatis-Plus 的設(shè)計(jì)決策,它將 delete 和 update 視為不同的操作,即使在邏輯刪除的情況下,delete 方法也不會(huì)觸發(fā)常規(guī)的更新字段填充。
注意事項(xiàng)
- 如果你手動(dòng)的設(shè)置了自動(dòng)填充的值,那么 MyBatis-Plus 的自動(dòng)填充策略不會(huì)覆蓋這個(gè)值。
- 字段必須聲明
@TableField注解,并設(shè)置fill屬性來(lái)選擇填充策略。 - 填充處理器需要在 Spring Boot 中聲明為
@Component或@Bean。 - 在
update(T entity, Wrapper<T> updateWrapper)時(shí),entity不能為空,否則自動(dòng)填充失效。 - 在
update(Wrapper<T> updateWrapper)時(shí)不會(huì)自動(dòng)填充,需要手動(dòng)賦值字段條件。
到此這篇關(guān)于Mybatis-Plus 自動(dòng)填充失效問(wèn)題解決的文章就介紹到這了,更多相關(guān)Mybatis-Plus 自動(dòng)填充失效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用Idea中的 Deployment 實(shí)現(xiàn)打包自動(dòng)部署
這篇文章主要介紹了使用Idea中的 Deployment 實(shí)現(xiàn)打包自動(dòng)部署,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
Java8 Supplier接口和Consumer接口原理解析
這篇文章主要介紹了Java8 Supplier接口和Consumer接口原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
mybatis-plus只查詢部分字段的三種實(shí)現(xiàn)方式
文章介紹了三種使用queryWrapper的select()方法查詢數(shù)據(jù)庫(kù)時(shí)指定要查詢的字段的方法,方法1查詢name和phone字段,其他字段值為null;方法2查詢除age和address外的其他字段,這兩個(gè)字段值為null;方法3使用selectMaps方法2025-11-11
Spring中EnvironmentAware 接口的使用小結(jié)
EnvironmentAware 是 Spring 框架中的一個(gè) Aware 回調(diào)接口,本文就來(lái)詳細(xì)的介紹一下Spring中EnvironmentAware 接口的使用小結(jié),感興趣的可以了解一下2026-04-04
全網(wǎng)最深分析SpringBoot MVC自動(dòng)配置失效的原因
這篇文章主要介紹了全網(wǎng)最深分析SpringBoot MVC自動(dòng)配置失效的原因,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
SpringBoot手把手實(shí)現(xiàn)生成PDF功能的示例代碼
這篇文章主要介紹了如何使用Thymeleaf模板和iText庫(kù)配合Flying-pdf工具,實(shí)現(xiàn)在業(yè)務(wù)系統(tǒng)中生成PDF文件的功能,感興趣的小伙伴可以了解下2025-12-12
MyBatis?連接緩慢問(wèn)題排查與解決實(shí)戰(zhàn)技巧
文章介紹了在維護(hù)一個(gè)老項(xiàng)目時(shí)遇到的MyBatis連接緩慢問(wèn)題的排查過(guò)程和解決方案,本文分階段給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2025-12-12
springboot將mybatis升級(jí)為mybatis-plus的實(shí)現(xiàn)
之前項(xiàng)目工程用的是mybatis,現(xiàn)在需要將其替換為mybatis-plus,本文主要介紹了springboot將mybatis升級(jí)為mybatis-plus的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
SpringBoot可視化接口開發(fā)工具magic-api的簡(jiǎn)單使用教程
作為Java后端開發(fā),平時(shí)開發(fā)API接口的時(shí)候經(jīng)常需要定義Controller、Service、Dao、Mapper、XML、VO等Java對(duì)象。有沒(méi)有什么辦法可以讓我們不寫這些代碼,直接操作數(shù)據(jù)庫(kù)生成API接口呢?今天給大家推薦一款工具magic-api,來(lái)幫我們實(shí)現(xiàn)這個(gè)小目標(biāo)!2021-06-06

