MyBatis-Plus 元对象处理器 @TableField注解 反射动态赋值 实现字段自动填充

目录

[🌰 举个直观例子](#🌰 举个直观例子)

[🛠️ 核心作用原理](#🛠️ 核心作用原理)

[📜 代码级工作流程](#📜 代码级工作流程)

[📜 完整代码](#📜 完整代码)

[🔍 关键概念拆解](#🔍 关键概念拆解)

[⚠️ 常见问题排查](#⚠️ 常见问题排查)

[🌟 设计意义](#🌟 设计意义)

🌰 举个直观例子

复制代码
package work.dduo.ans.domain;

import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

/**
 * 
 * @TableName t_visit_log
 */
@TableName(value ="t_visit_log")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TVisitLog implements Serializable {
    /**
     * id
     */
    @TableId(type = IdType.AUTO)
    private Integer id;

    /**
     * 访问ip
     */
    private String ipAddress;

    /**
     * 访问地址
     */
    private String ipSource;

    /**
     * 操作系统
     */
    private String os;

    /**
     * 访问时间
     * 使用mybatis-plus的元对象处理器自动填充
     */
    @TableField(fill=FieldFill.INSERT)
    private Date createTime;

    private static final long serialVersionUID = 1L;

}

假设你每次保存订单时都要记录 "订单创建时间"

  • 没有元对象处理器 :每次插入数据都要手动写 order.setCreateTime(new Date())
  • 有了元对象处理器:你只需专注业务逻辑,框架自动帮你填充这个时间

🛠️ 核心作用原理

  1. 拦截数据库操作
    MyBatis-Plus 在执行 insert()update() 操作时,会触发元对象处理器。
  2. 通过注解识别目标字段
    字段上的 @TableField(fill = FieldFill.INSERT) 注解会告诉处理器:"这个字段需要自动填充"。
  3. 反射动态赋值
    处理器利用反射机制,通过 MetaObject 对象直接操作实体类的字段值(无需手动调用 set 方法)。

📜 代码级工作流程

以你的 createTime 字段为例:

复制代码
// 1. 你的实体类标记了自动填充
public class TVisitLog {
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
}

// 2. 插入操作时自动触发
TVisitLog log = new TVisitLog();
visitLogMapper.insert(log); // ← 这里自动填充 createTime

// 3. 处理器内部执行(伪代码)
class MyMetaObjectHandler {
    void insertFill() {
        if (字段有 @TableField(fill=INSERT)) {
            用反射给字段赋值 new Date()
        }
    }
}

📜 完整代码

复制代码
package work.dduo.ans.handler;

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

import java.util.Date;

@Component
public class MyMetaObjectHandler  implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }

}

🔍 关键概念拆解

|----------------------|------------------------------------------|
| 概念 | 说明 |
| MetaObject | 对实体类的动态包装器,提供反射操作字段的能力(类似一个能透视对象内部结构的工具) |
| FieldFill | 填充策略枚举,包含 INSERT(插入时填充)、UPDATE(更新时填充)等 |
| strictInsertFill | 严格模式填充方法,确保字段存在且类型匹配 |


⚠️ 常见问题排查

如果自动填充失效,检查:

  1. 处理器类是否添加了 @Component 注解
  2. 实体类字段名与处理器中写的名称是否完全一致(包括大小写)
  3. 是否在主启动类的扫描范围内(位于同一包或子包)
  4. 数据库字段是否有默认值冲突(建议同时设置数据库默认值 CURRENT_TIMESTAMP

🌟 设计意义

通过元对象处理器,实现了:

业务代码与非业务逻辑解耦 (时间记录等通用操作集中管理)

消除重复代码 (避免每个插入操作都写 setCreateTime)

保证数据一致性(比如强制所有表统一使用同一时间生成规则)

相关推荐
mysqloffice5 小时前
数智时代,核心系统数据库架构往哪走
数据库·人工智能
l1t6 小时前
DeepSeek总结的 pgColumnar 1.0-alpha4 发布说明
数据库·postgresql
DBA_G6 小时前
南大通用GBase 8s数据库助力某农商行核心系统投产
数据库
Bs_MoneyMagnet6 小时前
基于springboot+vue的非遗物质文化遗产系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
万物智能6 小时前
波形发生AD9833模块配置—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
java
计算机毕设定制辅导-无忧学长6 小时前
《基于SpringBoot的未成年人健康知识科普平台的设计与实现》
java·开发语言·vue.js·spring boot·未成年人健康知识科普平台
Wang's Blog6 小时前
Java 项目实战: 外卖平台-数据库环境搭建与十一张表结构解析
java·服务器·redis
工业涂料百问6 小时前
【环保合规】系列(四)工业涂料碳足迹怎么算?边界定义、因子选择与减排优先级拆解
数据库
Ivanqhz6 小时前
Ping-Pong 双缓冲
开发语言·人工智能·python·深度学习·mlir
m0_734571766 小时前
深入理解C++ RAII
开发语言·c++