MyBatis Plus 自动填充功能 – MetaObjectHandler

2023-12-07 13:48:51 浏览数 (1)

MyBatis Plus 提供了自动填充(MetaObjectHandler)的功能,可以在插入和更新操作时自动填充指定的字段,例如创建时间、更新时间、创建人、更新人等。这样可以简化开发,减少重复的代码编写,提高开发效率。

在 MyBatis Plus 中,要实现自动填充功能,通常需要创建一个实现了 MetaObjectHandler 接口的类,并在该类中重写相应的方法来实现字段的填充逻辑。常用的方法包括 insertFillupdateFill,分别用于在插入和更新操作时填充字段的值。

以下是一个简单的示例:

代码语言:javascript复制
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        if (getFieldValByName("createTime", metaObject) == null) {
            this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        }
        if (getFieldValByName("createUser", metaObject) == null) {
            this.strictInsertFill(metaObject, "createUser", String.class, "system");
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        if (getFieldValByName("updateTime", metaObject) == null) {
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        }
        if (getFieldValByName("updateUser", metaObject) == null) {
            this.strictUpdateFill(metaObject, "updateUser", String.class, "system");
        }
    }
}

在这个示例中,我们创建了一个名为 MyMetaObjectHandler 的类,实现了 MetaObjectHandler 接口,并重写了 insertFillupdateFill 方法。在 insertFill 方法中,我们为 createTimecreateUser 字段如果为空的时候填充了默认值,在 updateFill 方法中,为 updateTimeupdateUser 字段填充了默认值。

通过这样的配置,当执行插入或更新操作时,MyBatis Plus 将自动填充这些字段的值,而无需手动编写重复的代码。

这种自动填充功能可以大大简化开发工作,尤其是在需要对多个表进行相同字段填充的情况下,能够提高开发效率并减少出错的可能性。

来自工作改装的代码

1、定义一个:BaseDO

注意有一点我暂时还没弄清楚 涉及自动填充的类,是否必须有一个属性被注解修饰:@TableField(fill = ) ,但是实际上:MetaObjectHandler实现类,全部都添加了某些属性的!不知道这个fill标记是否有鸟用,记录下但没测试!

代码语言:javascript复制
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import org.apache.ibatis.type.JdbcType;

import java.io.Serializable;
import java.time.LocalDateTime;

@Data
public abstract class BaseDO implements Serializable {
    /**
     * 创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 最后更新时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    /**
     * 创建者,使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。
     */
    @TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR)
    private String creatorId;

    /**
     * 更新人,使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。
     */
    @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.VARCHAR)
    private String updaterId;

    /**
     * 是否删除 0=不删除 1=删除
     */
    @TableLogic
    private Byte deleted;
}

2、编写自动填充逻辑:MyBatisPlusAutoFIllConfig

代码语言:javascript复制
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.zanglikun.springdataredisdemo.pojo.BaseDO;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Objects;

@Configuration
public class MyBatisPlusAutoFIllConfig implements MetaObjectHandler {
    /**
     * 插入元对象字段填充(用于插入时对公共字段的填充)
     *
     * @param metaObject 元对象
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 插入对象必须Object
        if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseDO) {
            BaseDO baseDO = (BaseDO) metaObject.getOriginalObject();

            LocalDateTime current = LocalDateTime.now();
            // 创建时间为空,则以当前时间为插入时间
            if (Objects.isNull(baseDO.getCreateTime())) {
                baseDO.setCreateTime(current);
            }
            // 更新时间为空,则以当前时间为更新时间
            if (Objects.isNull(baseDO.getUpdateTime())) {
                baseDO.setUpdateTime(current);
            }

            String userId = getLoginUserId();
            // 默认一个用户
            if (StringUtils.isEmpty(userId)) {
                userId = "0";
            }
            // 当前登录用户不为空,创建人为空,则当前登录用户为创建人
            if (StringUtils.isEmpty(baseDO.getCreatorId())) {
                baseDO.setCreatorId(userId);
            }
            // 当前登录用户不为空,更新人为空,则当前登录用户为更新人
            if (StringUtils.isEmpty(baseDO.getUpdaterId())) {
                baseDO.setUpdaterId(userId);
            }
        }
    }


    /**
     * 更新元对象字段填充(用于更新时对公共字段的填充)
     *
     * @param metaObject 元对象
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        // 更新时间为空,则以当前时间为更新时间
        Object modifyTime = getFieldValByName("updateTime", metaObject);
        if (Objects.isNull(modifyTime)) {
            setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }

        // 当前登录用户不为空,更新人为空,则当前登录用户为更新人
        Object modifier = getFieldValByName("updaterId", metaObject);
        String userId = getLoginUserId();
        //默认一个用户
        if (StrUtil.isEmpty(userId)) {
            userId = "0";
        }
        if (Objects.isNull(modifier)) {
            setFieldValByName("updaterId", userId, metaObject);
        }
    }

    /**
     * 自定义方法,从请求头重获取登录人信息。
     *
     * @return 登录信息
     */
    private String getLoginUserId() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (!(requestAttributes instanceof ServletRequestAttributes)) {
            return null;
        }
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        return servletRequestAttributes.getRequest().getHeader("userId");
    }
}

特殊说明: 上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com 第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤

0 人点赞