关于mybatisplus与mybatis的自动填充混用问题

public class MybatisPlusAutoFillHandler implements MetaObjectHandler {

    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //三个参数:字段名,字段值,元对象参数
        this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("createUser", BaseContext.getCurrentId(), metaObject);
        this.setFieldValByName("updateUser", BaseContext.getCurrentId(), metaObject);
        log.info("end insert fill ....");
    }

    //修改时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateUser", BaseContext.getCurrentId(), metaObject);
        log.info("start update fill ....");
    }
}

上述为mp的自动填充策略处理器

  //创建时间
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

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

上述为entity层的内容,tablefield注解中说明了这个属性是在新增/更新的时候会修改

以上为mybatisplus的自动填充策略,需要添加一个处理器,在实体类中写好注解。

但是,这里也出现了一个问题:一旦我们不使用mybatisplus的函数式编程方法,而是再在mapper层中添加新的自定义的方法,上述注解就会不再生效。

当然,问题也不是不可以解决,我们只需要再启动mybatis的自动填充策略,即可解决上述问题:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //指定数据操作类型
    OperationType value();

}

上述内容定义了@Autofill注解

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut() {
    }
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
        OperationType operationType = autoFill.value();//获得了操作类型insert / update

        Object[] args = joinPoint.getArgs();
        if (args == null || args.length == 0) {
            return;
        }
        //这里约定mapper层的第一个参数为实体
        Object object = args[0];

        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        if (operationType == OperationType.UPDATE) {
            Method setUpdateTime = object.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            setUpdateTime.invoke(object,now);
        } else if (operationType==OperationType.INSERT){
            Method setCreateTime = object.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
            Method setUpdateTime = object.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
            setCreateTime.invoke(object,now);
            setUpdateTime.invoke(object,now);
        }
    }
}

上述内容为自动填充内容的切面函数,尤其需要注意的是:这个方法中约定了:mapper层的第一个参数必须为实体

@AutoFill(value = OperationType.UPDATE)
    void mUpdate(Category category);

最后在mapper层中我们只需要添加上述注解即可实现mybatis的自动填充策略


总结:

在我们使用mybatisplus与mybatis的时候,

自动填充策略是可以混用的,

但是我们只写了mybatisplus的自动填充策略是不可以为自己手写的mybatis服务的,

而我们写的mybatis的自动填充策略只能应用于mapper层,mybatisplus也不能适用。

也就是说,mybatis与mybatisplus的使用必须分清楚,以免造成多余的混淆与不便

posted @ 2024-01-26 18:50  天启A  阅读(26)  评论(0)    收藏  举报