用 MyBatis-Plus MetaObjectHandler 统一处理公共字段,减少重复代码

每次插入都要写 createTime = now()
修改都要手动设 updateTime
用户信息还要到处传?

MyBatis-Plus 的 MetaObjectHandler 来接管这些重复逻辑

🐛 问题背景:公共字段的“重复赋值”问题

在大多数系统中,几乎每张表都有这些字段:

字段名含义赋值时机
id主键(雪花算法)插入时
create_time创建时间插入时
update_time更新时间插入/更新时
create_by创建人插入时
update_by更新人更新时
delete_flag逻辑删除标志插入时默认 false

传统做法

order.setCreateTime(new Date());
order.setCreateBy(UserContext.getCurrentUser().getUsername());
order.setDeleteFlag(false);
orderService.save(order);

👉 问题来了

  • 每个接口都要写这些赋值逻辑,代码冗余
  • 容易遗漏(比如忘了设 deleteFlag

 解决方案:MyBatis-Plus MetaObjectHandler 统一处理

✅ 自定义元对象处理器

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        AuthUser authUser = UserContext.getCurrentUser();
        String username = authUser != null ? authUser.getUsername() : "SYSTEM";

        // 创建人
        setFieldValByName("createBy", username, metaObject);

        // 创建时间(仅当字段存在且为空时)
        if (hasEmptyField(metaObject, "createTime")) {
            setFieldValByName("createTime", new Date(), metaObject);
        }

        // 逻辑删除标志(默认 false)
        if (hasEmptyField(metaObject, "deleteFlag")) {
            setFieldValByName("deleteFlag", false, metaObject);
        }

        // 主键 ID(仅当未设置时)
        if (hasEmptyField(metaObject, "id")) {
            setFieldValByName("id", SnowFlake.getId(), metaObject); // 注意:返回 long
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        AuthUser authUser = UserContext.getCurrentUser();
        if (authUser != null) {
            setFieldValByName("updateBy", authUser.getUsername(), metaObject);
        }

        // 更新时间(仅当字段存在时)
        if (metaObject.hasGetter("updateTime")) {
            setFieldValByName("updateTime", new Date(), metaObject);
        }
    }

    /**
     * 判断字段是否存在且值为空
     */
    private boolean hasEmptyField(MetaObject metaObject, String fieldName) {
        return metaObject.hasGetter(fieldName) && metaObject.getValue(fieldName) == null;
    }
}

调用时只需:

Order order = new Order();
order.setOrderNo("NO20250902001");
order.setTotalAmount(new BigDecimal("999.00"));

orderService.save(order); // ⚡ 自动填充 id, createTime, createBy, deleteFlag

当然有些业务必须“提前知道 ID”【如生成订单操作,会创建订单记录和订单详情记录(绑定了orderId)】,hasEmptyField 更多是一种保底,建议在日常开发中手动给Id赋值

MetaObjectHandler 不仅消灭了重复代码,还让系统更规范、更健壮。
但记住:自动化不是万能的
像订单这种“强关联”场景,需要提前生成 ID

参考:

SpringBoot+Mybatis-Plus 基于MetaObjectHandler实现公共字段动态赋值前言 最近在工 - 掘金https://juejin.cn/post/7405473135535063074

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值