MybatisPlus实现自动填充实体类字段值

        在软件开发中,实体类的公共字段(如 create_time、update_time、create_by、update_by 等)频繁需要根据业务规则赋值。传统实现方式通常通过手动编码为这些字段赋值,例如在插入或更新操作前,显式调用 setCreateTime(new Date()) 或从上下文中获取操作人信息。然而,这种模式存在明显痛点:

        1. ‌代码冗余‌:每个涉及公共字段的实体类都需要重复编写赋值逻辑,导致代码臃肿。

         2. ‌维护成本高‌:若字段规则变更(如时间格式调整、操作人来源切换),需全局搜索并修改所有相关代码。

        3. ‌数据一致性风险‌:人为遗漏赋值或逻辑错误可能导致字段数据缺失或不准确(例如未刷新 update_time)。  

        MyBatis-Plus 作为 MyBatis 的增强工具,通过 ‌字段自动填充机制‌ 提供了一种优雅的解决方案。开发者仅需通过简单的注解配置,即可将公共字段的赋值逻辑从业务代码中解耦,由框架在数据操作时自动触发。这种设计不仅减少了冗余代码,还能通过统一规则保障数据准确性,尤其适用于多团队协作或复杂业务场景下的高效开发。 本文将以实际场景为例,解析如何利用 MyBatis-Plus 的 @TableField 注解与 MetaObjectHandler 接口,快速实现字段自动填充,并探讨其底层实现原理与最佳实践。

一、导入依赖

        在项目的pom.xml文件中导入必要的依赖:

    
    
        com.baomidou
        mybatis-plus-boot-starter
        3.5.3.1 
    
    
    
    
        mysql
        mysql-connector-java
        8.0.33 
    

    
    
        com.baidu.fsg
        uid-generator
    

二、创建自定义的 MetaObjectHandler 实现类

        MetaObjectHandler接口定义了两个主要的方法

  • insertFill(MetaObject metaObject):当执行插入操作时,MyBatis-Plus 会自动调用该方法,你可以在这个方法中为需要自动填充的字段设置值。
  • updateFill(MetaObject metaObject):当执行更新操作时,MyBatis-Plus 会自动调用该方法,你可以在这个方法中为需要自动填充的字段设置值。

        下面是一个示例,展示如何创建一个自定义的 MetaObjectHandler 实现类,用于自动填充创建时间和更新时间:

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

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Autowired
    private CachedUidGenerator cachedUidGenerator;

    @Override
    public void insertFill(MetaObject metaObject) {

        // 自动填充全局id
        if (this.getFieldValByName(BaseEntity.Fields.id, metaObject) == null) {
            long id = cachedUidGenerator.getUID();
            this.setFieldValByName(BaseEntity.Fields.id, id, metaObject);
        }

        // 自动填充创建时间
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
        // 自动填充更新时间
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 自动填充更新时间
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }
}

        在上述代码中:

  • strictInsertFill 方法用于在插入操作时填充字段值,它接收四个参数:MetaObject 对象、字段名、字段类型和要填充的值。
  • strictUpdateFill 方法用于在更新操作时填充字段值,参数与 strictInsertFill 类似。

 三、在实体类中标记需要自动填充的字段

        使用 @TableField 注解的 fill 属性来标记哪些字段需要进行自动填充。示例如下:

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;

@TableName("your_table_name")
public class YourEntity {

    @TableId(type = IdType.INPUT)
    private Long id;

    private String name;

    // 插入时自动填充
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    // 插入和更新时都自动填充
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    // getter 和 setter 方法
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }
}

        在上述代码中:

  • @TableField(fill = FieldFill.INSERT) 表示该字段在插入操作时自动填充。
  • @TableField(fill = FieldFill.INSERT_UPDATE) 表示该字段在插入和更新操作时都自动填充。

 四、使用 MyBatis-Plus 进行插入和更新操作

        在使用 MyBatis-Plus 的 BaseMapper 进行插入和更新操作时,MetaObjectHandler 会自动工作,为标记的字段填充相应的值。示例如下:

 

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;

@Repository
public interface YourEntityMapper extends BaseMapper {
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class YourEntityService {

    @Autowired
    private YourEntityMapper yourEntityMapper;

    public void insertEntity(YourEntity entity) {
        yourEntityMapper.insert(entity);
    }

    public void updateEntity(YourEntity entity) {
        yourEntityMapper.updateById(entity);
    }
}

 五、总结

        通过实现 MetaObjectHandler 接口,你可以方便地实现数据库插入和更新操作时的自动填充功能,提高代码的可维护性和开发效率。

你可能感兴趣的:(java,spring,开发语言)