• 苍穹外卖--实现公共字段自动填充


    也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。在上述的问题分析中,我们提到有四个公共字段,需要在新增/更新中进行赋值操作。
    实现步骤:*

    1). 自定义注解 AutoFill,用于标识需要进行公共字段自动填充的方法

    2). 自定义切面类 AutoFillAspect,统一拦截加入了 AutoFill 注解的方法,通过反射为公共字段赋值

    3). 在 Mapper 的方法上加入 AutoFill 注解

    **技术点:**枚举、注解、AOP、反射

    步骤一

    自定义注解 AutoFill

    /**
     * 自定义注解,用于标识某个方法需要进行功能字段自动填充处理
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AutoFill {
        //数据库操作类型:UPDATE INSERT
        OperationType value();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    其中OperationType已在sky-common模块中定义

    package com.sky.enumeration;
    
    /**
     * 数据库操作类型
     */
    public enum OperationType {
    
        /**
         * 更新操作
         */
        UPDATE,
    
        /**
         * 插入操作
         */
        INSERT
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    步骤二

    自定义切面 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[0];
    
            //准备赋值的数据
            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();
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    步骤三 在Mapper接口的方法上加入 AutoFill 注解

    @AutoFill(value = OperationType.UPDATE)
        void update(Employee employee);
    
    • 1
    • 2
    @AutoFill(value = OperationType.INSERT)
        @Insert("insert into employee(name, username, password, phone, sex, id_number, create_time, update_time, create_user, update_user,status) " +
                "values (#{name},#{username},#{password},#{phone},#{sex},#{idNumber},#{createTime},#{updateTime},#{createUser},#{updateUser},#{status})")
        void save(Employee employee);
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    抖音视频评论采集软件|抖音数据抓取工具
    SSM学习47:SpringMvc五种参数传递
    十年老程序员给我的一些C语言建议,真的是受益终生!
    骁龙咣咣咣三脚,再次改写格局
    美国FBA海运详解:美国FBA海运费用价格有哪些
    网络安全70部学员第二阶段项目验收顺利结束
    深度学习基础知识——从人工神经网络开始
    迟迟没学会grid,是因为你没理解flex
    Java NIO ByteBuffer原理使用图文详解
    XSS 攻击是什么?
  • 原文地址:https://blog.csdn.net/m0_57682986/article/details/134481477