代码自动填充--springboot--项目开发

代码自动填充

引言:

  • 关于代码自动填充,在项目开发当中,有许多重复代码,而使用代码自动填充,可以让我们不去写那么多重复的代码,大大提高写代码的效率,比如,在项目中,新增的时候会有新增时间,新增人,修改的时候有修改时间,修改人,一个一个写,太浪费时间了,每次对数据进行新增、修改和删除都需要对这些字段进行设置。传统的做法是在进行这些操作前,对实体类的字段进行set赋值,然后再进行数据库操作。这种做法的坏处不仅容易忘记导致出错、而且显得代码冗余。

问题分析

  • 创建时间,创建人,修改时间,修改人等字段都属于公共字段,能否将这些公共字段在某个地方统一处理,来简化开发呢?

自定义注解:

  • 首先,定义一个自定义注解

  • @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AutoFill {
        OperationType value();//OperationType类是一个枚举类,里面定义了两个属性,insert和update
    }
    

枚举类

  • 枚举类

  • /**
     * 数据库操作类型
     */
    public enum OperationType {
        /**
         * 更新操作
         */
        UPDATE,
        /**
         * 插入操作
         */
        INSERT
    }
    

切面类

  • 再创建一个切面类,用来实现自动填充

  • /**
     * 自定义切面,实现公共字段自动填充处理逻辑
     */
    @Aspect
    @Component
    @Slf4j
    public class AutoFillAspect {
    
        /**
         * 切入点
         */
        @Pointcut("execution(* com.XXX.mapper.*.*(..)) && @annotation(com.XXX.annotation.AutoFill)")//直接在mapper包中找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[0];//让实体类都在0号索引,需要开发人员之间约定好,将实体类入参时放在第一个位置
    
            //准备赋值的数据
            LocalDateTime now = LocalDateTime.now();
            Long currentId = BaseContext.getCurrentId();//封装ThreadLocal
    
            //根据当前不同的操作类型,为对应的属性通过反射来赋值
            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();
                }
            }
        }
    }
    
    • 注意Object entity = args[0];//让实体类都在0号索引,需要开发人员之间约定好,将实体类入参时放在第一个位置
    • 注意@Pointcut("execution(* com.XXX.mapper.*.*(..)) && @annotation(com.XXX.annotation.AutoFill)")//直接在mapper包中找AutoFill注解,快

使用自定义注解:

  • 在mapper中的更新和插入接口加上我们自定义的注解,@AutoFill

  • @AutoFill(value = OperationType.UPDATE)
    void update(Employee employee);
    
  • 这时,自动填充就做好了
    但是,有一个新的问题,怎样获取修改人的id呢?我这里用的是ThreadLocal,如需了解请转到ThreadLocal文章

你可能感兴趣的:(springboot,java,spring,boot,vue)