关于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的使用必须分清楚,以免造成多余的混淆与不便

浙公网安备 33010602011771号