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

news2024/10/6 12:28:17

 问题分析

代码冗余,且不便于后期维护。

 实现思路

 

 技术点:枚举,注解,AOP,反射

 1.自定义注解AutoFill

1.在sky-server.com.sky包下建立annotation(注解)包

2.在该包下建立注解AutoFill

package com.sky.annotation;

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 {
    //数据库操作类型
    OperationType value();//可以通过这个方法设置数据库操作类型,也可以通过这个方法取出数据库的操作类型
}

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

1.在sky-server.com.sky包下建立aspect(切面)包

 2.在该包下建立切面类AutoFillAspect

package com.sky.aspect;

import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.Method;
import java.time.LocalDateTime;

/*
* 自定义切面,实现公共字段自动填充处理逻辑
* */
@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();//获得方法签名对象(默认获得的是Signnature类型的对象)
        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 {
                /*利用反射获取实体对象的方法
                (必须利用反射,
                1是因为返回类型是Object,无法直接调用对应方法;
                2是利用反射可以增强代码的复用性,不局限于一个实体类中)*/
                Method setCreateTime = entity.getClass().getMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
                Method setUpdateTime = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setCreateUser = entity.getClass().getMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
                Method setUpdateUser = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                //方法.invoke(实体对象,对应方法的参数);
                setCreateTime.invoke(entity,now);
                setUpdateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateUser.invoke(entity,currentId);

            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }else if(operationType==OperationType.UPDATE){
            //为2个字段赋值
            try {
                //Method setUpdateTime = entity.getClass().getMethod("setUpdateTime", LocalDateTime.class);
                //Method setUpdateUser = entity.getClass().getMethod("setUpdateUser", Long.class);
                //为了避免方法名写错,所以单独为方法名写了一个AutoFillConstant常量类(更加的规范和优雅)
                Method setUpdateTime = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                throw new RuntimeException(e);
             }
        }
    }
}

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

 

 1.在sky-server.com.sky.mapper包下为加入了Insert和update注解的方法再加入@AutoFfill注解。

2.将sky-server.com.sky.service.impl下使用到insert和update的方法中对字段数据的更新注释掉。(避免重复调用)

 小tips:

 1.利用反射获取实体对象的方法 (必须利用反射, 1是因为返回类型是Object,无法直接调用对应方法; 2是利用反射可以增强代码的复用性,不局限于一个实体类中)

2.为了避免方法名写错,所以单独为方法名写了一个AutoFillConstant常量类(这样可以使得代码更加的规范和优雅)

3.在获取当前被拦截的方法的参数时,会默认获取的第一个参数为所求实体(entity)对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试员,面试常见的18个问题(记得收藏!)

软件测试面试18个常见问题汇总 Q1:项目中相关需求问题,测试可以直接和客户沟通吗? A1:可以,最初与客户沟通需求时,测试人员直接参与,所以我们可以直接和客户方的代表开会进行沟通。 A2&#xff…

Apipost教程?一篇文章玩转Apipost

你是否经常遇到接口开发过程中的各种问题?或许你曾为接口测试与调试的繁琐流程而烦恼。不要担心!今天我将向大家介绍一款功能强大、易于上手的接口测试工具——Apipost,并带你深入了解如何玩转它,轻松实现接口测试与调试。 什么是…

SQL-每日一题【1173. 即时食物配送 I】

题目 配送表: Delivery 如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。 查询即时订单所占的百分比, 保留两位小数。 查询结果如下所示。 示例 1: 解题思路 1.题目要求我们查询出顾客期望的配送日…

大数据开发面试必问:Hive调优技巧系列一

Hive必问调优 Hive 调优拆解:Hive SQL 几乎是每一位互联网分析师的必备技能,相信很多小伙伴都有被面试官问到 Hive 优化问题的经历。所以掌握扎实的 HQL 基础尤为重要,hive优化也是小伙伴应该掌握的一项技能,本篇文章具体从hive建表优化、HQ…

我求求你不要再问我SpringBoot的自动配置原理了!

目录 四、SpringBoot自动配置原理 4.1 起步依赖原理 4.1.1 版本锁定 4.1.2 起步依赖 4.2 自动配置原理 4.2.1 SpringBootApplication源码 4.2.2 SpringBootConfiguration源码 4.2.3 EnableAutoConfiguration源码 1)Registrar 2)AutoConfigurat…

SQL SERVER使用发布订阅同步数据库遇到的坑

可能遇到的各种坑 1.在执行 xp_cmdshell 的过程中出错。调用 ‘CreateProcess’ 失败,错误代码: ‘5’ 网上有各种解决办法,包括改本地安全策略,将sql server服务的网络权限改为本机系统,改cmd用户的读写权限,退出360…

MIT 6.S081 Lab Eight -- Lock

MIT 6.S081 Lab Eight -- Lock 引言locksMemory allocator(moderate)代码解析 Buffer cache(hard)代码解析 可选的挑战练习 引言 本文为 MIT 6.S081 2020 操作系统 实验八解析。 MIT 6.S081课程前置基础参考: 基于RISC-V搭建操作系统系列 locks 在本实验中,您将获…

备战秋招 | 笔试强训19

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、二分查找的时间复杂度() A. O(N*log(N)) B. O(N) C. O(log(N)) D. O(N^2) 2、有一个单向链表中有一个A、B两个相邻元素,有一个指针p指向元素A,现将…

81%的消费者预算增加,今年返校季会有哪些机会?

对于跨境卖家来说,7-9月的重头戏莫过于“返校季”。多项调研表明,今年“返校季”消费者预计投入更多预算,并瞄准线上渠道。目前,亚马逊“返校季”促销活动正在火热进行中,许多产品甚至卖到脱销。 那么,今年…

​LeetCode解法汇总143. 重排链表

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:143. 重排链表 描述: 给定一个单链表 L 的头节点 head ,单链表 L 表示为&#x…

资深测试老鸟,APP性能测试-全覆盖测试点(详细整理)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 android的app性能…

QT控件中,便捷定义信号和槽函数

QT控件中,便捷定义信号和槽函数 之前使用的方式为:自定义信号和槽函数 现在使用一种更方便的方式: 点击控件,直接可以调用槽函数了。。。(都不用绑定) 把另外两个控件都加上

【MySQL】mysql | linux | 离线安装mysqldump

一、说明 1、项目要求离线安装mysqldump 2、数据库服务已经使用docker进行安装,但是其他项目依赖mysqldump,所以需要在宿主机上安装mysqldum 二、解决方案 1、下载依赖 https://downloads.mysql.com/archives/community/ 2、下载内容 mysql-community-c…

uniapp小程序警告:[sitemap 索引情况提示]

这个并不算是报错,只是一个警告提示,提示开发者哪些页面被微信收录了(代表这个页面可以在微信的搜索中被搜到),sitemap 的索引提示是默认开启的,如需要关闭 sitemap 的索引提示,可在小程序项目配…

【腾讯云 Cloud Studio 实战训练营】当我还在恐龙扛狼,隔壁IDE竟然已经卷成这样了

文章目录 前言关于cloud studio功能介绍账号注册小试牛刀深度体验使用场景和产品优势总结 手动bgm:沃没K~ 恐龙扛浪扛浪扛~ 恐龙扛浪扛浪扛~ 沃没K~ 布鲁biu布鲁biu~ 前言 上周很荣幸被邀请体验一款腾讯的新产品cloud studio,是一款在线ide,…

多元函数的极值和最值

目录 无约束极值 极值的必要条件 驻点和极值点的关系 多元函数极值点可能取的点: 极值的充分条件 条件极值与拉格朗日乘数法 最大最小值 例题 例题1: 例题2: ​编辑 例题3: 例题4: ​编辑 例题5: 例…

DuDuTalk:AI语音工牌如何帮助教培公司高效管理课程顾问团队

近年来,随着人工智能的快速发展,越来越多的公司开始利用AI技术来提高工作效率和管理效果。在教育培训行业中,课程顾问团队的管理对于公司的运营和发展至关重要。 而在实际管理中,受教培人员素质参差不齐,能力差异大&a…

Java课题笔记~Maven基础知识

一、什么是Maven? Maven是专门用于管理和构建Java项目的工具。 它的主要功能有: 提供了一套标准化的项目结构提供了一套标准化的构建流程(编译,测试,打包,发布……)提供了一套依赖管理机制 …

python小游戏课程设计报告,python游戏课程设计报告

大家好,给大家分享一下python2048游戏课程设计报告,很多人还不知道这一点。下面详细解释一下。现在让我们来看看!

安装java11( 安装jdk11)记录

下载JDK11 国内华为镜像下载:https://repo.huaweicloud.com/java/jdk/11.0.29/injdk 镜像下载:https://www.injdk.cn/官网下载:https://www.oracle.com/java/technologies/downloads/#java11 个人使用华为镜像下载 安装 下载后上传至Lin…