MyBatis Plus 中 update_time 字段自動填充失效的原因分析及解決方案

? MyBatis Plus 中 update_time 字段自動填充失效的原因分析及解決方案

  • 前言
  • 一、問題現象
  • 二、原因分析
    • 1. 使用了 `strictInsertFill/strictUpdateFill` 導致更新失效
    • 2. 實體類注解配置錯誤
    • 3. `MetaObjectHandler` 未生效
    • 4. 使用自定義 SQL 導致自動填充失效
    • 5. 字段類型不匹配
  • 三、總結:常見原因與解決方法對照表
  • 四、推薦寫法


前言

在使用 MyBatis Plus 時,通常我們會在數據庫表中設置 create_timeupdate_time 兩個字段,借助 MyBatis Plus 的 自動填充功能 來維護這些時間字段。

但是,有時候你可能會遇到 update_time 字段未自動更新的情況,哪怕代碼中已經配置了 MetaObjectHandler。本文將針對這一問題,分析可能的原因,并提供詳細的解決方案。


一、問題現象

假設我們有如下的 updateFill() 方法:

@Override
public void updateFill(MetaObject metaObject) {log.info("執行更新填充...");this.strictInsertFill(metaObject, "updateTime", Timestamp.class, Timestamp.valueOf(LocalDateTime.now())); this.strictInsertFill(metaObject, "updateBy", BigInteger.class, userId); 
}

但是執行更新操作后:

  • 數據庫中的 update_time 字段未更新

  • 沒有報錯,但 updateTime 依然是舊值

  • updateBy 可能也未更新

接下來我們來分析可能的原因。


二、原因分析

1. 使用了 strictInsertFill/strictUpdateFill 導致更新失效

  • 原因:

    strictInsertFill/strictUpdateFill 主要用于插入數據時的自動填充。即使在 updateFill() 中使用它,也不會生效。

  • 原理解釋:

    strictInsertFill/strictUpdateFill 的作用是 如果字段已有值則不會覆蓋,而在更新場景中,一般實體對象中 update_time 已有值。

  • 解決方案:

    strictInsertFill/strictUpdateFill 替換為 setFieldValByName

    @Override
    public void updateFill(MetaObject metaObject) {log.info("start update fill ....");this.setFieldValByName("updateTime", Timestamp.valueOf(LocalDateTime.now()), metaObject);this.setFieldValByName("updateBy", userId, metaObject);
    }
    
  • 原因分析補充:

    • strictInsertFill/strictUpdateFill插入/更新數據時填充,不適用于更新場景。

    • setFieldValByName → 更新數據時直接覆蓋字段值,即使原值存在。


2. 實體類注解配置錯誤

  • 原因:

    實體類中的字段沒有正確標注 @TableField(fill = FieldFill.INSERT_UPDATE),導致自動填充機制無法生效。

  • 解決方案:

    在實體類中正確設置注解:

    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.TableField;
    import lombok.Data;
    import java.time.LocalDateTime;@Data
    public class User {private Long id;private String name;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT_UPDATE)private BigInteger updateBy;
    }
    
  • 注意:

    • FieldFill.INSERT_UPDATE:用于插入和更新時自動填充。

    • 如果沒有加上這個注解,MyBatis Plus 不會執行自動填充邏輯。

3. MetaObjectHandler 未生效

  • 原因:

    MetaObjectHandler 需要被 Spring 管理。如果沒有加上 @Component 注解或沒有被掃描到,自動填充方法不會執行。

  • 解決方案:

    確保 FieldAutoFillHandler 類上有 @Component 注解:

    import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.reflection.MetaObject;
    import org.springframework.stereotype.Component;@Slf4j
    @Component
    public class FieldAutoFillHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("執行插入填充...");this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);}@Overridepublic void updateFill(MetaObject metaObject) {log.info("執行更新填充...");this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);}
    }
    
  • 注意:

    如果項目中有多個 MetaObjectHandler,需要確保不會有沖突。

4. 使用自定義 SQL 導致自動填充失效

  • 原因:

    如果你在 Mapper.xml 中自定義了 update 語句,那么 MyBatis Plus 不會觸發自動填充邏輯。

  • 解決方案:

    • 方法 1:在 XML 中手動設置 update_time 字段:

      <update id="updateUser" parameterType="com.example.entity.User">UPDATE userSET name = #{name},update_time = NOW(),update_by = #{updateBy}WHERE id = #{id}
      </update>
      
    • 方法 2:直接使用 BaseMapper 提供的 updateById() 等方法,MyBatis Plus 會自動觸發填充:

      User user = userMapper.selectById(1L);
      user.setName("李四");
      userMapper.updateById(user);
      

5. 字段類型不匹配

  • 原因:

    數據庫中 update_time 的數據類型與 Java 實體類的類型不匹配,導致填充失敗。

  • 解決方案:

    確保數據庫字段類型和實體類一致:

    ALTER TABLE user
    MODIFY update_time TIMESTAMP NULL DEFAULT NULL;
    
    private LocalDateTime updateTime;
    
  • 注意:

    • 使用 LocalDateTime 處理時間字段是最佳實踐。

    • 如果數據庫字段為 datetimetimestamp,不要使用 String 類型。

三、總結:常見原因與解決方法對照表

原因現象解決方法
使用了 strictInsertFillupdate_time 未更新使用 setFieldValByName 替代
實體類注解錯誤自動填充無效確保字段上加了 @TableField(fill = FieldFill.INSERT_UPDATE)
MetaObjectHandler 未生效updateFill() 不執行確保加上 @Component 注解
使用自定義 SQL 覆蓋了默認方法填充邏輯未觸發使用 BaseMapper.updateById() 或在 SQL 中手動填充
數據類型不匹配字段更新失敗數據庫字段使用 timestamp 且實體類使用 LocalDateTime

四、推薦寫法

最終推薦的 updateFill() 寫法如下:

@Override
public void updateFill(MetaObject metaObject) {log.info("執行更新填充...");this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);this.setFieldValByName("updateBy", userId, metaObject);
}

通過這種方式,確保 update_time 字段在更新時自動更新,同時避免了不必要的填充失效問題。

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

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

相關文章

C++ STL常用算法之常用算術生成算法

常用算術生成算法 學習目標: 掌握常用的算術生成算法 注意: 算術生成算法屬于小型算法&#xff0c;使用時包含的頭文件為 #include <numeric> 算法簡介: accumulate // 計算容器元素累計總和 fill // 向容器中添加元素 accumulate 功能描述: 計算區間內容器元素…

axios基礎入門教程

一、axios 簡介 axios 是一個基于 Promise 的 HTTP 客戶端&#xff0c;可用于瀏覽器和 Node.js 環境&#xff0c;支持以下特性&#xff1a; 發送 HTTP 請求&#xff08;GET/POST/PUT/DELETE 等&#xff09; 攔截請求和響應 自動轉換 JSON 數據 取消請求 并發請求處理 二…

短視頻團隊架構工作流程---2025.3.30 李劭卓

短視頻團隊架構&工作流程—2025.3.30 李劭卓 文章目錄 短視頻團隊架構&工作流程---2025.3.30 李劭卓1 工作職責1.1 編劇&#xff1a;1.2 主編&#xff1a;1.3 總編&#xff1a;1.4 導演&#xff1a;1.5 攝影&#xff1a;1.6 演員&#xff1a;1.7 后期&#xff1a;1.8 美…

MySQL 高效 SQL 使用技巧詳解

MySQL 高效 SQL 使用 技巧詳解 一、為什么需要優化 SQL&#xff1f; 性能瓶頸&#xff1a;慢查詢導致數據庫負載升高&#xff0c;響應時間延長。資源浪費&#xff1a;低效 SQL 可能占用大量 CPU、內存和磁盤 I/O。 目標&#xff1a;通過優化 SQL 將查詢性能提升 10 倍以上&am…

AI基礎03-視頻數據采集

上篇文章我們學習了圖片的數據采集&#xff0c;今天主要了解一下視頻數據采集的方法。視頻是由一系列圖像構成的&#xff0c;其中每一張圖片就是一幀。視頻數據采集方法通常有自動圖像采集和基于處理器的圖像采集兩種。我們學習一下如何利用python 工具和筆記本計算機攝像頭進行…

Scala 數組

Scala 數組 引言 Scala 作為一門多范式編程語言&#xff0c;融合了面向對象和函數式編程的特點。數組是編程語言中非常基礎和常見的數據結構&#xff0c;在 Scala 中也不例外。本文將詳細介紹 Scala 中的數組&#xff0c;包括其定義、操作以及在實際開發中的應用。 Scala 數…

Text-to-SQL將自然語言轉換為數據庫查詢語句

有關Text-To-SQL方法&#xff0c;可以查閱我的另一篇文章&#xff0c;Text-to-SQL方法研究 直接與數據庫對話-text2sql Text2sql就是把文本轉換為sql語言&#xff0c;這段時間公司有這方面的需求&#xff0c;調研了一下市面上text2sql的方法&#xff0c;比如阿里的Chat2DB,麻…

golang 的strconv包常用方法

目錄 1. 字符串與整數的轉換 2. 字符串與浮點數的轉換 3. 布爾值的轉換 4. 字符串的轉義 5. 補充&#xff1a;rune 類型的使用 方法功能詳解 代碼示例&#xff1a; 1. 字符串與整數的轉換 方法名稱功能描述示例Atoi將字符串轉換為十進制整數。strconv.Atoi("123&q…

MATLAB詳細圖文安裝教程(附安裝包)

前言 MATLAB&#xff08;Matrix Laboratory&#xff09;是由MathWorks公司開發的一款高性能的編程語言和交互式環境&#xff0c;主要用于數值計算、數據分析和算法開發。內置數學函數和工具箱豐富&#xff0c;開發效率高&#xff0c;特別適合矩陣運算和領域特定問題。接下來就…

ShapeCrawler:.NET開發者的PPTX操控魔法

引言 在當今的軟件開發領域&#xff0c;隨著數據可視化和信息展示需求的不斷增長&#xff0c;處理 PPTX 文件的場景日益頻繁。無論是自動化生成報告、批量制作演示文稿&#xff0c;還是對現有 PPT 進行內容更新與格式調整&#xff0c;開發者都需要高效的工具來完成這些任務。傳…

HTML5貪吃蛇游戲開發經驗分享

HTML5貪吃蛇游戲開發經驗分享 這里寫目錄標題 HTML5貪吃蛇游戲開發經驗分享項目介紹技術棧核心功能實現1. 游戲初始化2. 蛇的移動控制3. 碰撞檢測4. 食物生成 開發心得項目收獲后續優化方向結語 項目介紹 在這個項目中&#xff0c;我使用HTML5 Canvas和原生JavaScript實現了一…

有關pip與conda的介紹

Conda vs. Pip vs. Virtualenv 命令對比 任務Conda 命令Pip 命令Virtualenv 命令安裝包conda install $PACKAGE_NAMEpip install $PACKAGE_NAMEX更新包conda update --name $ENVIRONMENT_NAME $PACKAGE_NAMEpip install --upgrade $PACKAGE_NAMEX更新包管理器conda update con…

【Linux】調試器——gdb使用

目錄 一、預備知識 二、常用指令 三、調試技巧 &#xff08;一&#xff09;監視變量的變化指令 watch &#xff08;二&#xff09;更改指定變量的值 set var 正文 一、預備知識 程序的發布形式有兩種&#xff0c;debug和release模式&#xff0c;Linux gcc/g出來的二進制…

【Ubuntu常用命令】

1.將本地服務器文件或文件夾傳輸到遠程服務器 文件 scp /data/a.txt administrator10.60.51.20:/home/administrator/ 文件夾 scp -r /data/ administrator10.60.51.20:/home/administrator/ 2.從遠程服務器傳輸文件到本地服務器 scp administrator10.60.51.20:/data/a.txt /h…

golang 的time包的常用方法

目錄 time 包方法總結 類型 time.Time 的方法 庫函數 代碼示例&#xff1a; time 包方法總結 類型 time.Time 的方法 方法名描述示例               ?Now()獲取當前時間和日期time.Now()Format()格式化時間為字符串time.Now().Format("2006-01-02 15…

Elasticsearch:使用 Azure AI 文檔智能解析 PDF 文本和表格數據

作者&#xff1a;來自 Elastic James Williams 了解如何使用 Azure AI 文檔智能解析包含文本和表格數據的 PDF 文檔。 Azure AI 文檔智能是一個強大的工具&#xff0c;用于從 PDF 中提取結構化數據。它可以有效地提取文本和表格數據。提取的數據可以索引到 Elastic Cloud Serve…

【ArcGIS操作】ArcGIS 進行空間聚類分析

ArcGIS 是一個強大的地理信息系統&#xff08;GIS&#xff09;軟件&#xff0c;主要用于地理數據的存儲、分析、可視化和制圖 啟動 ArcMap 在 Windows 中&#xff0c;點擊“開始”菜單&#xff0c;找到 ArcGIS文件夾&#xff0c;然后點擊 ArcMap 添加數據 添加數據 - 點擊工具…

RabbitMQ消息相關

MQ的模式&#xff1a; 基本消息模式&#xff1a;一個生產者&#xff0c;一個消費者work模式&#xff1a;一個生產者&#xff0c;多個消費者訂閱模式&#xff1a; fanout廣播模式&#xff1a;在Fanout模式中&#xff0c;一條消息&#xff0c;會被所有訂閱的隊列都消費。 在廣播…

緩存使用紀要

一、本地緩存&#xff1a;Caffeine 1、簡介 Caffeine是一種高性能、高命中率、內存占用低的本地緩存庫&#xff0c;簡單來說它是 Guava Cache 的優化加強版&#xff0c;是當下最流行、最佳&#xff08;最優&#xff09;緩存框架。 Spring5 即將放棄掉 Guava Cache 作為緩存機…

2025年3月29日筆記

問題&#xff1a;創建一個長度為99的整數數組&#xff0c;輸出數組的每個位置數字是幾&#xff1f; 解題思路&#xff1a; 1.因為題中沒有明確要求需要輸入,所以所有類型的答案都需要寫出 解法1&#xff1a; #include<iostream> #include<bits/stdc.h> using n…