Mybatis-Plus 自動填充失效問題解決
確認(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
方法來設(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 及以上版本中引入的更高級的填充策略。它使用 strictInsertFill
和 strictUpdateFill
方法,這些方法更加類型安全,也提供了更靈活的填充選項(xiàng)。此版本推薦使用 java.time.LocalDateTime
類型,這符合 Java 8 及更高版本中引入的時間 API,提供了更好的日期和時間處理能力。
詳細(xì)對比:
類型安全性:
第二種寫法中,strictInsertFill
和 strictUpdateFill
方法允許你指定目標(biāo)字段的數(shù)據(jù)類型(例如 LocalDateTime.class
),從而避免了類型轉(zhuǎn)換錯誤。
第一種寫法中,setFieldValByName
方法需要你自己確保字段類型和賦值類型的一致性。
默認(rèn)值提供方式:
第二種寫法中,你可以直接傳遞一個 LocalDateTime.now()
表達(dá)式,或者使用 lambda 表達(dá)式 () -> LocalDateTime.now()
來提供一個延遲執(zhí)行的默認(rèn)值。這在某些情況下可能更有用,比如當(dāng)你的默認(rèn)值依賴于一些業(yè)務(wù)邏輯時。
第一種寫法直接使用 new Date()
創(chuàng)建日期實(shí)例,沒有提供延遲執(zhí)行的機(jī)制。
兼容性和 bug 修復(fù):
第二種寫法是 MyBatis-Plus 推薦的最新實(shí)踐,通常意味著它有更好的兼容性和已知問題的修復(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 自動填充配置 */ @Bean public MetaObjectHandler metaObjectHandler(){ return new MetaObjectHandler() { @Override public void insertFill(MetaObject metaObject) { /** * 第一個參數(shù) metaObject 這里面包含了你傳入的實(shí)體類 * 第二個參數(shù)要和實(shí)體類中的屬性名保持一致 * 第三個參數(shù)要跟實(shí)體類中的屬性類型保持一致 * 第四個參數(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
注解來標(biāo)記哪些字段需要自動填充,并指定填充的策略。
public class User { @TableField(fill = FieldFill.INSERT) private String createTime; @TableField(fill = FieldFill.UPDATE) private String updateTime; // 其他字段... }
delete 和 update 方法的區(qū)別
在 MyBatis-Plus 中,`delete` 方法和 `update` 方法的行為差異主要源于它們對 `MetaObjectHandler` 中定義的自動填充邏輯的調(diào)用時機(jī)和方式的不同。
對于 update
方法:
當(dāng)你使用 update 方法時,MyBatis-Plus 會調(diào)用 MetaObjectHandler 的 updateFill 方法。這是因?yàn)?nbsp;update 方法本質(zhì)上是一個更新操作,它會觸發(fā)自動填充邏輯,尤其是那些被標(biāo)記為 FieldFill.UPDATE 或 FieldFill.INSERT_UPDATE 的字段。
對于 delete
方法:
當(dāng)使用 delete 方法時,情況就有所不同了。默認(rèn)情況下,delete 方法不會觸發(fā) MetaObjectHandler 的 updateFill 方法,即使你正在使用邏輯刪除(即,delete 方法實(shí)際上執(zhí)行的是一個 UPDATE 語句來修改一個邏輯刪除標(biāo)志)。這是因?yàn)樵?MyBatis-Plus 的設(shè)計中,delete 方法的目的就是刪除記錄,無論是物理刪除還是邏輯刪除,它都不會觸發(fā)更新字段的自動填充邏輯。
然而,當(dāng)你在實(shí)體類中使用了 @TableLogic 注解并配置了邏輯刪除,MyBatis-Plus 的 delete 方法會執(zhí)行一個 UPDATE 語句來改變邏輯刪除字段的值,但它不會執(zhí)行 updateFill 方法來更新其他字段,如 updatedDate。這是 MyBatis-Plus 的設(shè)計決策,它將 delete 和 update 視為不同的操作,即使在邏輯刪除的情況下,delete 方法也不會觸發(fā)常規(guī)的更新字段填充。
注意事項(xiàng)
- 如果你手動的設(shè)置了自動填充的值,那么 MyBatis-Plus 的自動填充策略不會覆蓋這個值。
- 字段必須聲明
@TableField
注解,并設(shè)置fill
屬性來選擇填充策略。 - 填充處理器需要在 Spring Boot 中聲明為
@Component
或@Bean
。 - 在
update(T entity, Wrapper<T> updateWrapper)
時,entity
不能為空,否則自動填充失效。 - 在
update(Wrapper<T> updateWrapper)
時不會自動填充,需要手動賦值字段條件。
到此這篇關(guān)于Mybatis-Plus 自動填充失效問題解決的文章就介紹到這了,更多相關(guān)Mybatis-Plus 自動填充失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中靜態(tài)訪問配置屬性的解決方案對比
在SpringBoot開發(fā)中,靜態(tài)訪問配置信息是一個常見需求,尤其是在工具類中直接獲取配置值,下面我們就來看看幾個常用的方法,大家可以根據(jù)需要選擇2025-03-03Java Socket實(shí)現(xiàn)多人聊天系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java Socket實(shí)現(xiàn)多人聊天系統(tǒng),具有圖形界面,實(shí)現(xiàn)文件傳輸功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-07-07Java二進(jìn)制操作(動力節(jié)點(diǎn)Java學(xué)院整理)
這篇文章給大家介紹了java二進(jìn)制操作技巧,包括移位、位運(yùn)算操作符等相關(guān)知識點(diǎn),非常不錯,感興趣的朋友參考下吧2017-03-03SpringBoot實(shí)現(xiàn)配置文件自動加載和刷新的示例詳解
在使用Spring Boot開發(fā)應(yīng)用程序時,配置文件是非常重要的組成部分,在不同的環(huán)境中,我們可能需要使用不同的配置文件,當(dāng)我們更改配置文件時,我們希望應(yīng)用程序能夠自動加載和刷新配置文件,本文我們將探討Spring Boot如何實(shí)現(xiàn)配置文件的自動加載和刷新2023-08-08反射機(jī)制:getDeclaredField和getField的區(qū)別說明
這篇文章主要介紹了反射機(jī)制:getDeclaredField和getField的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06SpringBoot實(shí)現(xiàn)動態(tài)插拔的AOP的完整案例
在現(xiàn)代軟件開發(fā)中,面向切面編程(AOP) 是一種非常重要的技術(shù),能夠有效實(shí)現(xiàn)日志記錄、安全控制、性能監(jiān)控等橫切關(guān)注點(diǎn)的分離,在傳統(tǒng)的 AOP 實(shí)現(xiàn)中,切面邏輯往往是固定的,難以動態(tài)調(diào)整,本文將詳細(xì)探討如何利用 Spring Boot 實(shí)現(xiàn)動態(tài)插拔的 AOP,需要的朋友可以參考下2025-01-01關(guān)于實(shí)體類中Date屬性格式化@JsonFormat @DateTimeFormat
這篇文章主要介紹了關(guān)于實(shí)體類中Date屬性格式化@JsonFormat @DateTimeFormat問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07SpringBoot3整合郵件服務(wù)實(shí)現(xiàn)郵件發(fā)送功能
本文介紹了spring boot整合email服務(wù),實(shí)現(xiàn)發(fā)送驗(yàn)證碼,郵件(普通文本郵件、靜態(tài)資源郵件、附件郵件),文中通過代碼示例介紹的非常詳細(xì),堅持看完相信對你有幫助,需要的朋友可以參考下2024-05-05springboot+mybatis-plus實(shí)現(xiàn)內(nèi)置的CRUD使用詳解
這篇文章主要介紹了springboot+mybatis-plus實(shí)現(xiàn)內(nèi)置的CRUD使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12