络腮胡菲菲 发表于 2024-8-23 14:02:06

实现 公共字段主动填充【创建时间/创建人/修改id/修改id】

实现 公共字段主动填充【创建时间/创建人/修改id/修改id】

技术栈


[*]枚举
[*]自定义注解
[*]AOP
[*]反射
实现思路


[*]编写枚举,用于标识数据库操作类型
[*]自定义注解AutoFill,用于标识须要进行公共字段主动填充的方法
[*]将Mapper的方法名写成常量类,提高代码规范
[*]自定义切面类AutoFillAspect,同一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
[*]在Mapper的方法上加入AutoFill注解
代码实现


[*]编写枚举,用于标识数据库操作类型
public enum OperationType {

    //更新操作
    UPDATE,

    //插入操作
    INSERT

}
[*]自定义注解AutoFill,用于标识须要进行公共字段主动填充的方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {

    //数据库操作类型
    OperationType value();
}
[*]将Mapper的方法名写成常量类,提高代码规范
//公共字段自动填充相关常量
public class AutoFillConstant {

    //实体类中的方法名称
    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";
}
[*]自定义切面类AutoFillAspect
/**
* 自定义切面,实现公共字段自动填充
*/
@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){
      log.info("开始进行公共字段自动填充...");

      //获取到当前被拦截的方法上的数据库操作类型
      MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
      AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
      OperationType operationType = autoFill.value();//获得数据库操作类型

      //获取到被拦截的方法形参参数【实体对象】
      Object[] args = joinPoint.getArgs();
      //约定:如果需要实现自动填充功能 ,需要把实体参数 放在形参第一个参数
      if (args == null || args.length == 0){
            return;//防止空指针
      }

      Object entity = args;//拿到实体对象

      //准备数据 实体对象的公共属性【时间和登录id】
      LocalDateTime now = LocalDateTime.now();
      Long currentId = BaseContext.getCurrentId();

      //根据当前不同的操作类型 为对应的属性赋值【反射】
      if (operationType == OperationType.INSERT){
            //为4个公共字段赋值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);//这里就是常量类,规范代码
                Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

                //通过反射为对象属性赋值
                setCreateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
               e.printStackTrace();
            }
      }else if (operationType == OperationType.UPDATE){
            //为2个公共字段赋值
            try {
                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,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }
      }
    }
}
[*]在Mapper的方法上加入AutoFill注解
@AutoFill(value = OperationType.INSERT)
    @Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user)" +
            " VALUES" +
            " (#{type}, #{name}, #{sort}, #{status}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})")
    void insert(Category category);
实现了表格公共字段主动填充后,在service层编写插入大概修改实体的时间就不须要重复设置 修改时间、修改id等
//设置修改时间、修改人
//      category.setUpdateTime(LocalDateTime.now());
//      category.setUpdateUser(BaseContext.getCurrentId());这些不再需要重复设置
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 实现 公共字段主动填充【创建时间/创建人/修改id/修改id】