mybatis-plus 公共字段填充(自定义)

mybatisplus带的公共字段自动填充

通常,记录数据时会存在公共字段,为了方便插入,可以使用mybatisplus带的公共字段自动填充, 例如:记录创建信息和更新信息

@ApiModelProperty(value = "创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
private Date createTime;

@ApiModelProperty(value = "创建人id")
@TableField(value = "create_user_id", fill = FieldFill.INSERT)
private Long createUserId;

@ApiModelProperty(value = "创建人姓名")
@TableField(value = "create_user_name", fill = FieldFill.INSERT)
private String createUserName;

@ApiModelProperty(value = "修改时间")
@TableField(value = "update_time", fill = FieldFill.UPDATE)
private Date updateTime;

@ApiModelProperty(value = "修改人id")
@TableField(value = "update_user_id", fill = FieldFill.UPDATE)
private Long updateUserId;

@ApiModelProperty(value = "修改人姓名")
@TableField(value = "update_user_name", fill = FieldFill.UPDATE)
private String updateUserName;

存在这么一种情况,当我没有赋值这个数据的时候自动插入,如果赋值了就插入自己的值。

自动填充步骤:

1、在实体类的属性上加入@TableField注解,指定自动填充策略

2、按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,需要实现MetaObjectHandler接口

3、 使用:

fill = FieldFill.INSERT                新增

fill = FieldFill.INSERT_UPDATE   新增和修改

fill = FieldFill.UPDATE        修改

CustomMetaObjectHandler.java

@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        //【注意】属性名称,不是字段名称
        if (Objects.isNull(curUserId) && metaObject.hasGetter("createUserId") && Objects.isNull(metaObject.getValue("createUserId"))) {
            this.setFieldValByName("createUserId", 1L, metaObject);
        }
        Object createUserId = this.getFieldValByName("createUserId", metaObject);
        //对于手动赋值的数据,不再自动赋值
        if(Objects.nonNull(createUserId))
        {
            //System.out.println(createUserId);
        }
        else if (Objects.nonNull(curUserId)) {
            this.setFieldValByName("createUserId", curUserId, metaObject);
        }

        Object createUserName = this.getFieldValByName("createUserName", metaObject);
        if(createUserName instanceof String && StringUtils.isNotBlank((String)createUserName))
        {
            //System.out.println(createUserName);
        }
        else
        {
            this.setFieldValByName("createUserName", CommonUtil.getCurrentUserName(), metaObject);
        }

        Object createTime = this.getFieldValByName("createTime", metaObject);
        if(createTime != null)
        {
//            System.out.println(createTime);
        }
        else
        {
            this.setFieldValByName("createTime", CommonUtil.getCurrentDate(), metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        //如果有需要,同上
        this.setFieldValByName("updateTime", CommonUtil.getCurrentDate(), metaObject);
        this.setFieldValByName("updateUserId", CommonUtil.getCurrentUserId(), metaObject);
        this.setFieldValByName("updateUserName", CommonUtil.getCurrentUserName(), metaObject);
    }
}

这里,如果存在项目中重写SqlSessionFactory,需要添加配置:

@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
    @Qualifier("mybatisPlusInterceptor") MybatisPlusInterceptor mybatisPlusInterceptor,
    CustomMetaObjectHandler customMetaObjectHandler
    ) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(buildDataSource());
        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/**/*.xml"));
        sessionFactoryBean.setPlugins(mybatisPlusInterceptor);
        GlobalConfig globalConfig = new GlobalConfig();
        //这里!!
        globalConfig.setMetaObjectHandler(customMetaObjectHandler);
        globalConfig.setSqlInjector(new MyInjector());
        sessionFactoryBean.setGlobalConfig(globalConfig);
        return sessionFactoryBean.getObject();
    }

【补充】

MybatisPlus字段更新策略FieldStrategy使用

Mybatis-plus默认的更新策略是NOT_NULL:非NULL,也就是传数据为NULL时不更新数据库中该字段的值。

Mybatis-plus通过updateById()更新数据,当传值为NULL且需要对该字段更新为NULL时,需要对FieldStrategy 策略进行调整。

public enum FieldStrategy {
    //忽略空值判断,实体对象的字段是什么值就用什么值更新,支持null值更新操作
    IGNORED,
    //非NULL判断
    NOT_NULL,
    //非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
    NOT_EMPTY,
    //默认
    DEFAULT,
    //不加入 SQL
    NEVER
}

第一种:在配置文件中全局配置

//默认都是DEFAULT,也就是NOT_NULL
mybatis-plus.global-config.db-config.update-strategy=not_null
mybatis-plus.global-config.db-config.insert-strategy=not_null
mybatis-plus.global-config.db-config.where-strategy=not_null

第二种:单个字段

@ApiModelProperty(value = "创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT, updateStrategy = FieldStrategy.IGNORED)
private Date createTime;

实战:

@Data
@TableName("rewrite_sql")
public class RewriteSqlDO implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.INPUT)
    private Integer id;

    private String stuName;

    private Integer age;

    @TableField(value = "create_time", fill = FieldFill.INSERT,  updateStrategy = FieldStrategy.IGNORED)
//    @TableField(value = "create_time", fill = FieldFill.INSERT,  updateStrategy = FieldStrategy.NOT_NULL)
//    @TableField(value = "create_time", fill = FieldFill.INSERT,  updateStrategy = FieldStrategy.NOT_EMPTY)
//    @TableField(value = "create_time", fill = FieldFill.INSERT,  updateStrategy = FieldStrategy.NEVER)
    private Date createTime;
}

初始值:

@Test
void test4() {
    //测试策略
    RewriteSqlDO rewriteSqlDO = new RewriteSqlDO();
    rewriteSqlDO.setId(1);
    rewriteSqlDO.setAge(2);
    rewriteSqlDO.setStuName(String.valueOf(2));
    //        rewriteSqlDO.setCreateTime(TimeUtil.sdfStrToDate("2023-12-31", "yyyy-MM-dd"));
    rewriteSqlMapper.updateById(rewriteSqlDO);
}

1、FieldStrategy.IGNORED

结果:忽略字段值的空值判断,无论实体对象的字段值是否为空,都会进行更新操作。

【注意:】如果传的值为空,则更新为NULL。

2、FieldStrategy.NOT_NULL

结果:进行NULL值判断,如果为NULL,则不更新对应的字段。

3、FieldStrategy.NOT_EMPTY

结果:字符串进行空值判断,只有非空字符串的字段才会参处理与数据。

结果:字符串进行空值判断,只有非空字符串的字段才会参处理与数据。

4、FieldStrategy.NEVER

结果:忽略字段值的空值判断,不管标识的字段是否有值,都不会进行更新操作。

@Test
void test4() {
    RewriteSqlDO rewriteSqlDO = new RewriteSqlDO();
    rewriteSqlDO.setId(1);
    rewriteSqlDO.setAge(2);
    rewriteSqlDO.setStuName(String.valueOf(2));
    rewriteSqlDO.setCreateTime(TimeUtil.sdfStrToDate("2023-12-31", "yyyy-MM-dd"));
    rewriteSqlMapper.updateById(rewriteSqlDO);
}

 

这里引出了一个问题: update_time字段未自动更新

当使用selectById()时,没有进行自动更新create_time。原因就是:默认的是NOT_NULL,当赋值的时候没有重新赋值这个值,那么就不会更新。

需要注意。解决方案如上,更换其他策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis-Plus提供了公共字段填充的功能,可以在插入和更新操作时自动填充公共字段,减少代码重复和出错的可能性。下面是Java代码实现公共字段填充的示例: 1. 创建公共字段填充器类 ```java @Component public class MyMetaObjectHandler implements MetaObjectHandler { // 插入时填充字段 private static final String CREATE_TIME = "createTime"; private static final String UPDATE_TIME = "updateTime"; private static final String CREATE_BY = "createBy"; private static final String UPDATE_BY = "updateBy"; @Override public void insertFill(MetaObject metaObject) { // 填充创建时间和更新时间 this.strictInsertFill(metaObject, CREATE_TIME, LocalDateTime::now, LocalDateTime.class); this.strictInsertFill(metaObject, UPDATE_TIME, LocalDateTime::now, LocalDateTime.class); // 填充创建人和更新人 this.strictInsertFill(metaObject, CREATE_BY, "system", String.class); this.strictInsertFill(metaObject, UPDATE_BY, "system", String.class); } @Override public void updateFill(MetaObject metaObject) { // 填充更新时间 this.strictUpdateFill(metaObject, UPDATE_TIME, LocalDateTime::now, LocalDateTime.class); // 填充更新人 this.strictUpdateFill(metaObject, UPDATE_BY, "system", String.class); } } ``` 2. 配置公共字段填充器 ```java @Configuration public class MybatisPlusConfig { @Autowired private MyMetaObjectHandler metaObjectHandler; @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加公共字段填充器 List<MetaObjectHandler> metaObjectHandlers = new ArrayList<>(); metaObjectHandlers.add(metaObjectHandler); interceptor.setMetaObjectHandlers(metaObjectHandlers); return interceptor; } } ``` 在以上示例中,我们创建了一个名为MyMetaObjectHandler的公共字段填充器类,实现了MetaObjectHandler接口,并在insertFill和updateFill方法中分别填充了创建时间、更新时间、创建人和更新人等公共字段。然后在MybatisPlusConfig中将MyMetaObjectHandler配置到MybatisPlusInterceptor中,作为公共字段填充器。这样,在执行插入和更新操作时,就会自动填充公共字段,无需手动设置,大大提高了开发效率和数据准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值