问题:进行对数据库的添加,修改时需要进行重复操作,例如设置更新时间,更新者,创建时间,创建者等字段,这时可使用公共字段自动填充(Aop+自定义注解)方法
添加自定义注解类:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface AutoFill {
OperationType value();
}
public enum OperationType {
/**
* 更新操作
*/
UPDATE,
/**
* 插入操作
*/
INSERT
}
进行切面的添加,对mapper层进行拦截
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
@Pointcut("execution(* com.sky.mapper.*.*(..))&&@annotation(com.sky.annotation.AutoFill)")
public void autoFillPointCut(){}
/**
* 在方法执行前自动填充实体类的公共字段。
* 通过注解@AutoFill指定需要自动填充的字段,根据操作类型(插入或更新)来决定填充哪些字段。
* 使用AOP(面向切面编程)的方式,对标注了@AutoFill注解的方法进行拦截,实现在方法执行前自动填充实体类的创建时间和更新时间,以及创建人和更新人的ID。
*
* @param joinPoint 切点,用于获取目标方法和方法参数等信息。
*/
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint){
// 日志记录开始进行公共字段自动填充
log.info("开始进行公共字段自动填充...");
// 获取方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 通过方法签名获取方法上的@AutoFill注解
AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);
// 从注解中获取操作类型
OperationType value = annotation.value();
// 获取方法参数
Object[] args = joinPoint.getArgs();
// 如果没有参数或参数为空,则直接返回,不进行填充
if (args == null||args.length == 0){
return;
}
// 将需要自动填充的字段填充到实体类放在第一个参数中,否证无法使用
Object arg = args[0];
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 获取当前操作人的ID
long id = BaseContext.getCurrentId();
try {
// 动态获取参数类的设置更新时间和更新人方法
Method setUpdateTime = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = arg.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
// 根据操作类型,执行不同的填充逻辑
switch (value) {
case INSERT -> {
// 动态获取参数类的设置创建时间和创建人方法
Method setCreateTime = arg.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setCreateUser = arg.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
// 填充创建时间和创建人
setCreateTime.invoke(arg, now);
setCreateUser.invoke(arg, id);
// 填充更新时间和更新人
setUpdateTime.invoke(arg, now);
setUpdateUser.invoke(arg, id);
}
case UPDATE -> {
// 填充更新时间和更新人
setUpdateTime.invoke(arg, now);
setUpdateUser.invoke(arg, id);
}
}
} catch (Exception e) {
// 打印异常堆栈信息
e.printStackTrace();
}
}
}
最后在方法上添加注解就能够使用
@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
@AutoFill(value = OperationType.INSERT)
int insert(Employee employee);
@AutoFill(value = OperationType.UPDATE)
@Override
int update(@Param("et") Employee entity, @Param("ew") Wrapper<Employee> updateWrapper);
}