最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis Plus實現(xiàn)時間字段自動填充的完整方案

 更新時間:2025年09月11日 10:45:44   作者:當歸1024  
在日常開發(fā)中,我們經(jīng)常需要記錄數(shù)據(jù)的創(chuàng)建時間和更新時間,傳統(tǒng)的做法是在每次插入或更新操作時手動設(shè)置這些時間字段,這種方式不僅繁瑣,還容易遺漏,本文將介紹如何使用 MyBatis Plus 的自動填充功能來優(yōu)雅地解決這個問題,需要的朋友可以參考下

前言

在日常開發(fā)中,我們經(jīng)常需要記錄數(shù)據(jù)的創(chuàng)建時間和更新時間。傳統(tǒng)的做法是在每次插入或更新操作時手動設(shè)置這些時間字段,這種方式不僅繁瑣,還容易遺漏。本文將介紹如何使用 MyBatis Plus 的自動填充功能來優(yōu)雅地解決這個問題。

解決目標

  • 創(chuàng)建記錄時自動設(shè)置 createTimeupdateTime
  • 更新記錄時自動更新 updateTime,保持 createTime 不變
  • 無需手動編寫時間設(shè)置代碼
  • 統(tǒng)一的時間管理機制

技術(shù)棧

  • 框架: Spring Boot + MyBatis Plus
  • 數(shù)據(jù)庫: MySQL
  • 實體管理: JPA 注解 + MyBatis Plus 注解

實現(xiàn)步驟

1. 實體類注解配置

首先在實體類的時間字段上添加 MyBatis Plus 的自動填充注解:

/**
 * 郵箱服務(wù)器實體類
 */
@Entity
@Table(name = "tbl_email_server")
public class EmailServer extends BaseEntity {
    
    // 其他字段...
    
    /** 創(chuàng)建時間 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    /** 更新時間 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT_UPDATE)  
    private Date updateTime;
    
    // getter 和 setter 方法...
}

注解說明:

  • @TableField(fill = FieldFill.INSERT): 僅在插入操作時自動填充
  • @TableField(fill = FieldFill.INSERT_UPDATE): 在插入和更新操作時都自動填充
  • @JsonFormat: 指定 JSON 序列化時的日期格式

2. 創(chuàng)建元數(shù)據(jù)處理器

創(chuàng)建自定義的元數(shù)據(jù)處理器來實現(xiàn)具體的填充邏輯:

package com.ruoyi.framework.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * MyBatis Plus 字段自動填充處理器
 * 
 * @author ruoyi
 */
@Component
public class MyBatisMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入時的填充策略
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        Date now = new Date();
        
        // 插入時同時填充創(chuàng)建時間和更新時間
        this.strictInsertFill(metaObject, "createTime", Date.class, now);
        this.strictInsertFill(metaObject, "updateTime", Date.class, now);
    }

    /**
     * 更新時的填充策略  
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        // 更新時僅填充更新時間
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

核心方法說明:

  • insertFill(): 處理插入操作的字段填充
  • updateFill(): 處理更新操作的字段填充
  • strictInsertFill(): 嚴格插入填充,只有當字段值為 null 時才填充
  • strictUpdateFill(): 嚴格更新填充,只有當字段值為 null 時才填充

3. 服務(wù)層代碼優(yōu)化

移除原本手動設(shè)置時間的代碼:

修改前:

@Override
public int insertEmailServer(EmailServer emailServer) {
    // 手動設(shè)置時間字段
    emailServer.setCreateBy(SecurityUtils.getUsername());
    emailServer.setCreateTime(new Date());  // ? 需要移除
    emailServer.setUpdateTime(new Date());  // ? 需要移除
    return emailServerMapper.insertEmailServer(emailServer);
}

@Override
public int updateEmailServer(EmailServer emailServer) {
    emailServer.setUpdateBy(SecurityUtils.getUsername());
    emailServer.setUpdateTime(new Date());  // ? 需要移除  
    return emailServerMapper.updateEmailServer(emailServer);
}

修改后:

@Override
public int insertEmailServer(EmailServer emailServer) {
    // 只設(shè)置創(chuàng)建者,時間字段由 MyBatis Plus 自動填充
    emailServer.setCreateBy(SecurityUtils.getUsername());
    return emailServerMapper.insertEmailServer(emailServer);
}

@Override
public int updateEmailServer(EmailServer emailServer) {
    // 只設(shè)置更新者,更新時間由 MyBatis Plus 自動填充
    emailServer.setUpdateBy(SecurityUtils.getUsername());
    return emailServerMapper.updateEmailServer(emailServer);
}

填充機制詳解

創(chuàng)建記錄時的填充過程

// 執(zhí)行插入操作
EmailServer emailServer = new EmailServer();
emailServer.setServerName("SMTP服務(wù)器");
// ... 設(shè)置其他業(yè)務(wù)字段

// 調(diào)用 insertEmailServer 時,MyBatis Plus 會:
// 1. 觸發(fā) insertFill 方法
// 2. createTime = 2024-01-15 10:30:25  
// 3. updateTime = 2024-01-15 10:30:25 (與創(chuàng)建時間相同)

更新記錄時的填充過程

// 執(zhí)行更新操作
EmailServer emailServer = new EmailServer();
emailServer.setServerId(1L);
emailServer.setServerName("新的服務(wù)器名稱");
// ... 修改其他業(yè)務(wù)字段

// 調(diào)用 updateEmailServer 時,MyBatis Plus 會:
// 1. 觸發(fā) updateFill 方法
// 2. createTime = 保持原值不變
// 3. updateTime = 2024-01-15 14:25:30 (更新為當前時間)

數(shù)據(jù)庫建議配置

雖然使用了注解自動填充,但建議在數(shù)據(jù)庫層面也設(shè)置默認值作為雙重保障:

-- 為時間字段添加默認值
ALTER TABLE tbl_email_server 
MODIFY COLUMN create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間';

ALTER TABLE tbl_email_server 
MODIFY COLUMN update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間';

前后對比

對比項手動設(shè)置方式自動填充方式
代碼量每個方法都需要設(shè)置一次配置,全局生效
維護性容易遺漏,難以統(tǒng)一統(tǒng)一管理,不易出錯
一致性依賴開發(fā)者自覺性自動保證一致性
性能無額外性能消耗微小的反射開銷

進階擴展

1. 支持更多字段類型

@Override
public void insertFill(MetaObject metaObject) {
    Date now = new Date();
    
    // 支持 Date 類型
    this.strictInsertFill(metaObject, "createTime", Date.class, now);
    this.strictInsertFill(metaObject, "updateTime", Date.class, now);
    
    // 支持 LocalDateTime 類型
    this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
    this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    
    // 支持時間戳
    this.strictInsertFill(metaObject, "createTime", Long.class, System.currentTimeMillis());
}

2. 添加創(chuàng)建者和更新者自動填充

@Override
public void insertFill(MetaObject metaObject) {
    Date now = new Date();
    String currentUser = getCurrentUser(); // 獲取當前用戶
    
    // 時間字段填充
    this.strictInsertFill(metaObject, "createTime", Date.class, now);
    this.strictInsertFill(metaObject, "updateTime", Date.class, now);
    
    // 用戶字段填充
    this.strictInsertFill(metaObject, "createBy", String.class, currentUser);
    this.strictInsertFill(metaObject, "updateBy", String.class, currentUser);
}

@Override  
public void updateFill(MetaObject metaObject) {
    String currentUser = getCurrentUser();
    
    this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    this.strictUpdateFill(metaObject, "updateBy", String.class, currentUser);
}

private String getCurrentUser() {
    try {
        return SecurityUtils.getUsername();
    } catch (Exception e) {
        return "system"; // 默認用戶
    }
}

常見問題與解決方案

1. 字段沒有自動填充

可能原因:

  • 實體類字段名與數(shù)據(jù)庫列名不匹配
  • 忘記添加 @TableField 注解
  • MetaObjectHandler 沒有被 Spring 管理

解決方案:

// 確保字段名正確映射
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;

// 確保處理器被 Spring 管理
@Component  // 必須添加此注解
public class MyBatisMetaObjectHandler implements MetaObjectHandler {
    // ...
}

2. 更新操作時創(chuàng)建時間被意外修改

解決方案:

// 使用 FieldFill.INSERT 而不是 INSERT_UPDATE
@TableField(fill = FieldFill.INSERT)  // ? 正確
private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)  // ? 正確
private Date updateTime;

3. JSON 序列化時間格式問題

解決方案:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

總結(jié)

MyBatis Plus 的自動填充功能為我們提供了一個優(yōu)雅的解決方案來管理時間字段:

優(yōu)勢

  1. 自動化: 無需手動編寫重復的時間設(shè)置代碼
  2. 統(tǒng)一性: 全局統(tǒng)一的時間填充策略
  3. 可靠性: 避免了人為遺漏設(shè)置時間的問題
  4. 擴展性: 可以輕松擴展到其他字段的自動填充

核心實現(xiàn)

  1. 在實體類時間字段添加 @TableField 注解
  2. 創(chuàng)建實現(xiàn) MetaObjectHandler 接口的處理器
  3. 在處理器中實現(xiàn) insertFillupdateFill 方法
  4. 移除服務(wù)層中的手動時間設(shè)置代碼

這種方案不僅提升了開發(fā)效率,還增強了代碼的可維護性和一致性。在實際項目中,建議結(jié)合數(shù)據(jù)庫默認值設(shè)置,形成雙重保障機制。

以上就是MyBatis Plus實現(xiàn)時間字段自動填充的完整方案的詳細內(nèi)容,更多關(guān)于MyBatis Plus時間字段自動填充的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中的深拷貝(深復制)和淺拷貝(淺復制)介紹

    Java中的深拷貝(深復制)和淺拷貝(淺復制)介紹

    這篇文章主要介紹了Java中的深拷貝(深復制)和淺拷貝(淺復制)介紹,需要的朋友可以參考下
    2015-03-03
  • java實現(xiàn)入棧push和出棧pop過程

    java實現(xiàn)入棧push和出棧pop過程

    文章詳細介紹了棧的概念、特點以及如何使用數(shù)組和鏈表實現(xiàn)棧,通過入棧(push)和出棧(pop)操作,展示了棧的數(shù)據(jù)處理過程,并提供了具體的代碼實現(xiàn)
    2024-12-12
  • Spring Boot應(yīng)用事件監(jiān)聽示例詳解

    Spring Boot應(yīng)用事件監(jiān)聽示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot應(yīng)用事件監(jiān)聽的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-12-12
  • mybatis調(diào)用mysql存儲過程并獲取返回值方式

    mybatis調(diào)用mysql存儲過程并獲取返回值方式

    這篇文章主要介紹了mybatis調(diào)用mysql存儲過程并獲取返回值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • java中將一個實體類復制到另一個實體類的3種方法示例

    java中將一個實體類復制到另一個實體類的3種方法示例

    這篇文章主要給大家介紹了關(guān)于java中將一個實體類復制到另一個實體類的3種方法,所謂實體類就是一個擁有Set和Get方法的類,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • 詳解Java中類的加載順序

    詳解Java中類的加載順序

    Java中什么時候類加載,第一次需要使用類信息時加載。類加載的原則:延遲加載,能不加載就不加載。下面這篇文章主要介紹了Java中類的加載順序,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • 關(guān)于IntelliJ IDEA 打包代碼報錯的問題

    關(guān)于IntelliJ IDEA 打包代碼報錯的問題

    這篇文章主要介紹了關(guān)于IntelliJ IDEA 打包代碼報錯的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • idea2020.3配置maven環(huán)境并配置Tomcat的詳細教程

    idea2020.3配置maven環(huán)境并配置Tomcat的詳細教程

    這篇文章主要介紹了idea2020.3配置maven環(huán)境并配置Tomcat的詳細教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Eclipse?Jetty?server漏洞解決辦法

    Eclipse?Jetty?server漏洞解決辦法

    最近給?個客戶部署項?,但是客戶的安全稽核有點變態(tài),居然說 Eclipse Jetty Server?危漏洞,這篇文章主要給大家介紹了關(guān)于Eclipse?Jetty?server漏洞解決的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java實現(xiàn)ThreadLocal數(shù)據(jù)在線程池間傳遞的解決方案

    Java實現(xiàn)ThreadLocal數(shù)據(jù)在線程池間傳遞的解決方案

    隨著業(yè)務(wù)的發(fā)展,系統(tǒng)新增了一個需求:需要根據(jù)接口請求頭中的特定信息動態(tài)選擇數(shù)據(jù)庫實例進行查詢,這個上下文信息在請求進入后被存儲在ThreadLocal中,本文給大家介紹了Java實現(xiàn)ThreadLocal數(shù)據(jù)在線程池間傳遞的解決方案,需要的朋友可以參考下
    2025-07-07

最新評論

平顶山市| 年辖:市辖区| 柳江县| 洞头县| 鄄城县| 平顶山市| 乐陵市| 天等县| 沂源县| 柳河县| 静海县| 澎湖县| 鹤壁市| 陇西县| 牟定县| 睢宁县| 花莲县| 五寨县| 浦北县| 兰坪| 通城县| 福贡县| 苍山县| 名山县| 澄城县| 库伦旗| 石台县| 北碚区| 韶关市| 湖南省| 天门市| 鄂伦春自治旗| 盐城市| 柳林县| 鄂托克前旗| 古丈县| 潢川县| 连州市| 余姚市| 申扎县| 南昌县|