公共字段填充

背景

这篇的公共字段填充主要是修改和插入一些数据的接口会用到,像一些实体类的创建时间、修改时间、创建人和修改人。

解决办法

自定义注解类AutoFill,标识需要公共字段填充的方法;

自定义切面类AutoFillAspect,统一拦截里加入AutoFill注解的方法,通过反射为其赋值;

在Mapper的方法上加上AutoFill注解;

实现

自定义注解代码实现:

import com.sky.enumeration.OperationType;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/*
* 自定义注解 用于标识自动填充处理
* */
@Target(ElementType.METHOD)//指定该注解只能被使用在方法上
@Retention(RetentionPolicy.RUNTIME) //指定该注解只能在运行时使用
public @interface AutoFill {
//    指定数据库操作类型,update insert
    OperationType value();
}

其中:定义了一个名为 OperationType 的枚举(Enum),枚举中有两个常量:UPDATE 和 INSERT。代码实现:

/**
 * 数据库操作类型
 */
public enum OperationType {

    /**
     * 更新操作
     */
    UPDATE,

    /**
     * 插入操作
     */
    INSERT

}

切面类代码实现:

import com.sky.annotation.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/*
* 自定义切面 实现公共字段自动填充的逻辑
* */
@Aspect
@Slf4j
@Component
public class AutoFillAspect {

    /*
    * 切入点
    * */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && " +
            "@annotation(com.sky.annotation.AutoFill)") //指定了拦截mapper包下的所有类所有方法 以及同时加入了AutoFill自定义注解的方法
    public void autoFillPointCut(){}


    /*
    * 前置通知 在该通知中进行公共字段的赋值
    * */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {  //传入一个参数 表示连接点
//        获取注解上面的方法的数据库类型是insert还是update
          MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获取一个 MethodSignature 对象,它包含了当前执行的方法的签名信息,比如方法名、参数类型等
          AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//从获得的signature对象中获取其方法 再获取名为AutoFill的注解
          OperationType operationType=autoFill.value(); //将获取到的有添加自定义注解的方法进行操作类型的获取 insert还是update
//        获取要赋值的实体对象 即被拦截的方法的参数
        Object[] args = joinPoint.getArgs();//获取参数
        if(args==null || args.length==0){
//            参数为空 直接return
            return;
        }
//        不为空 获取参数列表中的第一个参数 例如 Employee employee 中的Employee
        Object object=args[0];
//        准备赋值的数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();
//        为对应的操作类型进行赋值
        if(operationType==OperationType.INSERT){
//            插入操作 为四个公共字段赋值
            Method setCreateTime=object.getClass()
                    .getDeclaredMethod("setCreateTime",LocalDateTime.class);//获取当前对象类的setCreateTime方法 并设置为其赋值一个 LocalDateTime 类型的参数
            Method setCreateUser = object.getClass()
                    .getDeclaredMethod("setCreateUser", Long.class);//与上面同理 只不过user是long型数据
            Method setUpdateTime=object.getClass()
                    .getDeclaredMethod("setUpdateTime",LocalDateTime.class);
            Method setUpdateUser = object.getClass()
                    .getDeclaredMethod("setUpdateUser", Long.class);

//            通过反射为对象属性赋值
            setCreateTime.invoke(object,now);
            setCreateUser.invoke(object,currentId);
            setUpdateTime.invoke(object,now);
            setUpdateUser.invoke(object,currentId);

        }else if(operationType==OperationType.UPDATE){

//            更新操作 为两个属性赋值即可
                Method setUpdateTime=object.getClass()
                        .getDeclaredMethod("setUpdateTime",LocalDateTime.class);
                Method setUpdateUser = object.getClass()
                        .getDeclaredMethod("setUpdateUser", Long.class);

                setUpdateTime.invoke(object,now);
                setUpdateUser.invoke(object,currentId);
            
        }

    }

}

随后,便可在需要的方法上面添加自定义注解来进行公共字段的填充:

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值