公共字段自动填充

出现的问题:

编写修改或添加功能时,都要在SQL语句中给修改时间、修改ID等公共字段进行赋值,显得很笨重、不灵活。从懒人角度来讲是没有必要的,浪费不必要的功。那我们可以如何解决?

解决方法:

我们可以使用动态代理的方法,对原有方法进行加强,在需要加强的方法上做个标记既可

运用技术:AOP

思路:

1、自定义注释

2、在需要加强的方法上添加该注解

3、实现自定义切面类,通过反射获取方法的注释,若有我们自定义的注释则进行加强

步骤:

0、准备阶段(根据个人情况而定)

/**
 * 公共字段自动填充相关常量
 */
public class AutoFillConstant {

    /**
     * 操作类型
     */
    public static final String INSERT = "insert";
    public static final String UPDATE = "update";


    /**
     * 实体类中的方法名称
     */
    public static final String SET_CREATE_TIME = "setCreateTime";
    public static final String SET_UPDATE_TIME = "setUpdateTime";
    public static final String SET_CREATE_USER = "setCreateUser";
    public static final String SET_UPDATE_USER = "setUpdateUser";
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;

    //。。。省略其他属性

    
    private LocalDateTime createTime;

    
    private LocalDateTime updateTime;

    private Long createUser;

    private Long updateUser;

}

1、自定义注释

/**
 * 自动填充
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //操作的类型:insert update
    String type();
}

2、实现相关逻辑的切面类

/**
 * 自定义切面类,统一为公共字段赋值
 */
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

    //切面 = 通知 + 切入点

    /**
     * 切入点
     */
    @Pointcut("execution(* com.reggie.mapper.*.*(..)) && @annotation(com.reggie.annotation.AutoFill)")
    public void autoFillPointCut() {
    }

    /**
     * 通知 自动填充公共字段
     *
     * @param joinPoint
     */
    @Before("autoFillPointCut()")
    public void AutoFillAdvice(JoinPoint joinPoint) {
        log.info("公共字段自动填充...");

        //获得方法签名对象
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获得方法上的注解
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        //获得注解中type的值
        String type = autoFill.type(); // insert update

        //获取当前目标方法的参数
        Object[] args = joinPoint.getArgs();
        //数值满足下面条件时,说明没有参数直接结束
        if (args == null || args.length == 0) {
            return;
        }

        //实体对象
        Object entity = args[0];

        //准备赋值的数据
        LocalDateTime time = LocalDateTime.now();
        Long empId = BaseContext.getCurrentId();

        if (type.equals(AutoFillConstant.INSERT)) {
            //当前执行的是insert操作,为4个字段赋值
            try {
                //获得set方法对象----Method
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //通过反射调用目标对象的方法
                setCreateTime.invoke(entity, time);
                setUpdateTime.invoke(entity, time);
                setCreateUser.invoke(entity, empId);
                setUpdateUser.invoke(entity, empId);
            } catch (Exception ex) {
                log.error("公共字段自动填充失败:{}", ex.getMessage());
            }
        } else {
            //当前执行的是update操作,为2个字段赋值
            try {
                //获得set方法对象----Method
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //通过反射调用目标对象的方法
                setUpdateTime.invoke(entity, time);
                setUpdateUser.invoke(entity, empId);
            } catch (Exception ex) {
                log.error("公共字段自动填充失败:{}", ex.getMessage());
            }
        }
    }

}

3、在需要加强的方法上使用自定义注释即可

如:

/**
 * 插入数据
 * @param employee
 */
@AutoFill(type = AutoFillConstant.INSERT)
void insert(Employee employee);
/**
 * 根据id修改员工信息
 * @param employee
 */
@AutoFill(type = AutoFillConstant.UPDATE)
void update(Employee employee);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值