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

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

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

前言

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

解決目標(biāo)

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

技術(shù)棧

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

實(shí)現(xiàn)步驟

1. 實(shí)體類注解配置

首先在實(shí)體類的時(shí)間字段上添加 MyBatis Plus 的自動(dòng)填充注解:

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

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

注解說明:

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

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

創(chuàng)建自定義的元數(shù)據(jù)處理器來實(shí)現(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 字段自動(dòng)填充處理器
 * 
 * @author ruoyi
 */
@Component
public class MyBatisMetaObjectHandler implements MetaObjectHandler {

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

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

核心方法說明:

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

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

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

修改前:

@Override
public int insertEmailServer(EmailServer emailServer) {
    // 手動(dòng)設(shè)置時(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)建者,時(shí)間字段由 MyBatis Plus 自動(dòng)填充
    emailServer.setCreateBy(SecurityUtils.getUsername());
    return emailServerMapper.insertEmailServer(emailServer);
}

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

填充機(jī)制詳解

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

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

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

更新記錄時(shí)的填充過程

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

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

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

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

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

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

前后對(duì)比

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

進(jìn)階擴(kuò)展

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());
    
    // 支持時(shí)間戳
    this.strictInsertFill(metaObject, "createTime", Long.class, System.currentTimeMillis());
}

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

@Override
public void insertFill(MetaObject metaObject) {
    Date now = new Date();
    String currentUser = getCurrentUser(); // 獲取當(dāng)前用戶
    
    // 時(shí)間字段填充
    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"; // 默認(rèn)用戶
    }
}

常見問題與解決方案

1. 字段沒有自動(dòng)填充

可能原因:

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

解決方案:

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

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

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

解決方案:

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

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

3. JSON 序列化時(shí)間格式問題

解決方案:

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

總結(jié)

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

優(yōu)勢(shì)

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

核心實(shí)現(xiàn)

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

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

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

相關(guān)文章

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

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

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

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

    文章詳細(xì)介紹了棧的概念、特點(diǎn)以及如何使用數(shù)組和鏈表實(shí)現(xiàn)棧,通過入棧(push)和出棧(pop)操作,展示了棧的數(shù)據(jù)處理過程,并提供了具體的代碼實(shí)現(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)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • mybatis調(diào)用mysql存儲(chǔ)過程并獲取返回值方式

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

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

    java中將一個(gè)實(shí)體類復(fù)制到另一個(gè)實(shí)體類的3種方法示例

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

    詳解Java中類的加載順序

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

    關(guān)于IntelliJ IDEA 打包代碼報(bào)錯(cuò)的問題

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

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

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

    Eclipse?Jetty?server漏洞解決辦法

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

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

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

最新評(píng)論

武汉市| 广州市| 将乐县| 丰原市| 绵竹市| 重庆市| 山阴县| 惠水县| 淅川县| 铜陵市| 绵竹市| 明星| 黔东| 揭西县| 白山市| 汕头市| 佛山市| 哈尔滨市| 巫山县| 海宁市| 昭平县| 常熟市| 射洪县| 布尔津县| 南昌县| 三穗县| 武功县| 庆元县| 昌图县| 虹口区| 武汉市| 榆中县| 墨玉县| 陆丰市| 景德镇市| 林州市| 阳城县| 菏泽市| 乾安县| 临邑县| 香河县|