spring boot加mybatis puls实现,在新增/修改时,对某些字段进行处理,使用的@TableField()或者AOP @Before

4 篇文章 0 订阅
4 篇文章 0 订阅

1.先说场景,在对mysql数据库表数据插入或者更新时都得记录时间和用户id

传统实现有点繁琐,这里还可以封装一下公共方法。

2.解决方法:

    2.1:使用aop切面编程(记录一下,有时间再攻克)。

        2.1.1:成功实现进行补充,感谢网友顶力相助(进步·于辰)

         2.1.2:在启动器上加   @EnableAspectJAutoProxy

         2.1.3:切入主要代码

@Aspect
@Component
@Slf4j
public class EntityAttrAspect {

    @Before("execution(* com.zuodou..*.save*(..))"+
          " ||execution(* com.zuodou..*.update*(..))"
    )
    public void before(JoinPoint joinPoint) throws Exception {
        log.info("切入");
        String userId = BaseUtlis.getCurrentUser().getId();// 管理员id
        Object[] args = joinPoint.getArgs();

        for (Object arg : args) {
            if (arg != null) {
                   Class<?> clazz = arg.getClass();
                    // 获取实体所有属性,进而获取主键属性。一般情况下,主键属性是第一个
                    Class<?> entityClass = clazz; // 使用clazz获取实体类的类型
                    Field[] entityFieldArr = entityClass.getDeclaredFields();
                    Field idField = entityFieldArr[0];// 主键属性
                    idField.setAccessible(true);//设置为可以访问
                    Object id = idField.get(arg); // 使用arg获取实体对象的主键值
                    if (id == null) {// 无主键,插入
                        if (StringUtils.isNotBlank(userId)){
                            entityAttrIoc(arg, "createBy", userId);// 创建人
                        }

                        entityAttrIoc(arg, "createTime", new Date());// 创建时间
                    } else {// 有主键,更新
                        if (StringUtils.isNotBlank(userId)){
                            entityAttrIoc(arg, "updateBy", userId);// 修改人
                        }
                        entityAttrIoc(arg, "updateTime", new Date());// 更新时间
                    }

            }
        }

    }

    // entityAttrIoc方法的定义可以是类似于下面这样的形式:
    private void entityAttrIoc(Object entity, String attributeName, Object value) throws Exception {
        Field field = entity.getClass().getDeclaredField(attributeName);
        field.setAccessible(true);
        field.set(entity, value);
    }

}

    注:

@Before("execution(* com.zuodou..*.save*(..))"+ " ||execution(* com.zuodou..*.update*(..))" )

切入点的表达式,不懂了可以先去了解表达式配置

我只需要判断新增还是修改,

Field idField = entityFieldArr[0];// 主键属性
idField.setAccessible(true);//设置为可以访问

我主键是由  file  和  static  修饰的  所以得加setAccessible

    2.2:使用@TableField()注解。

3.我使用的@TableField  注解实现,因为没有很多的业务处理,单纯的记录一下,以下是具体实现

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        // 在插入时自动填充 create_time 和 update_time 字段
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "createBy", String.class, BaseUtlis.getCurrentUser().getId());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 在更新时自动填充 update_time 字段
        this.strictUpdateFill(metaObject, "updateTime",Date.class, new Date());
        this.strictInsertFill(metaObject, "updateBy", String.class, BaseUtlis.getCurrentUser().getId());
    }
}

注: 字段需要跟实体类对应起来,我项目架构是使用了驼峰命名使用下划线后字母大写。BaseUtlis.getCurrentUser().getId(),这个是我封装的一个获取当前登录用户的方法。

参数解析:

this.strictUpdateFill(metaObject, "updateTime",Date.class, new Date());

metaObject:对象

updateTime:实体类目标字段

Date.class:数据类型

new Date():具体值

4.yml配置

mybatis-plus:
  global-config:
    db-config:
      meta-object-handler: com.zuodou.mymeta.MyMetaObjectHandler

5.在对应实体类的字段上加

@TableField(fill = FieldFill.UPDATE)

或者

@TableField(fill = FieldFill.INSERT)

6.补充缺陷

直接在controllerdi调用根据id修改方法   或者 update 批量根据id修改, 会不触发自动填充

解决使用update,条件传入id或者在service调用,而updateBatchById就需要手动传了。

至于为什么在service调用updateById就能触发

在 MyBatis Plus 中,通常通过继承 ServiceImpl 类来实现 Service 层的操作。这个类提供了一些默认的 CRUD(增删改查)方法,并且默认情况下会使用 MyBatis Plus 的内置功能,比如自动填充。
当你在自己的 Service 类中继承了 ServiceImpl 并且指定了泛型类型,比如 YourService extends ServiceImpl&lt;YourMapper, YourEntity&gt;,这样就将 YourService 和 YourEntity 关联起来了。
MyBatis Plus 的 ServiceImpl 已经预先实现了一些常见的操作方法,其中包括了自动填充的支持。在这个类中,如果你调用了 updateById 方法,它内部会调用 MyBatis Plus 的自动填充逻辑,以便在更新数据时触发自动填充。
当然,前提是你需要做以下几件事情:

1.确保你的实体类中的字段有正确地标注了自动填充的注解,比如使用了 @TableField 注解并设置了相应的 fill 属性。
2.确保你已经正确配置了 MetaObjectHandler,并且这个配置被正确地注册到了 Spring 容器中。这样 MyBatis Plus 才能正确地使用自动填充功能。

因此,当你在自定义的 Service 类中继承了 ServiceImpl,就相当于在你的 Service 类中内置了 MyBatis Plus 提供的默认实现,包括自动填充的支持。这样,在调用 updateById 等方法时,会自动触发 MyBatis Plus 的自动填充逻辑。

(侵权联系删除)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值