JAVA项目开发公共字段自动填充——省事

news2024/11/18 5:29:07
  业务表中,有时候会有公共的字段需要反复的赋值,最常见的就是每次操作都会记录更新日期,更新人等。

     为了避免反复的赋值操作—— 我们可以用自定义注解加上自定义切面,还有反射来一次性设置多次使用。

 1.首先自定义一个注解,用于表示需要进行公共字段填充的方法:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
//    数据库操作类型:UPDATE INSERT
    OperationType value();
}

这段代码是一个自定义注解 AutoFill,用于标记方法,并指定一个注解参数 value() 来表示数据库的操作类型。下面是对这段代码的解释:

  • @Target(ElementType.METHOD):表示该注解可以应用于方法上。
  • @Retention(RetentionPolicy.RUNTIME):表示该注解在运行时仍然可用,可以通过反射来获取注解信息。
  • public @interface AutoFill:定义了一个名为 AutoFill 的注解。

注解参数部分的解释如下:

  • OperationType value():该注解参数表示数据库的操作类型,类型为 OperationType 。OperationType 可以是一个枚举类型,用来表示数据库的更新操作(如更新数据、插入数据等)。
  • 枚举示例(表示数据库操作的类型)

通过使用这个自定义注解,开发者可以在方法上标记需要进行自动填充的操作,并通过 value() 参数指定数据库的操作类型,用于后续的处理和判断。

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

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    /**
     * 切入点 (对哪些类的哪些方法进行拦截)
     * @PointCut(切点表达式)
     *  表示匹配 com.sky.mapper 包及其子包中的所有类的所有方法,并且这些方法必须同时带有 com.sky.annotation.AutoFill 注解。
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
    public void autoFillPointCut(){}


    /**
     * 自定义前置通知:在通知中进行公共字段的赋值
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint)  {
        log.info("开始进行公共字段自动填充..");

        //1.获取到当前被拦截的方法上的数据库操作类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解对象
        OperationType op = autoFill.value();//获取数据库操作类型
        //2.获取到当前被拦截的方法的参数--实体对象
        Object[] args = joinPoint.getArgs();
        if(args == null || args.length ==0) {
            return;
        }
        //约定好实体类放在参数的第一个位置
        Object entity = args[0];
        //3.准备赋值数据
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();

        //4.根据当前不同的操作类型,为对应的属性通过反射赋值
        if(op == 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(op == OperationType.UPDATE) {
               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();
            }

        }

    }
}

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

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

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

相关文章

C++—数组

数组是由一批相同类型的元素&#xff08;element&#xff09;的集合所组成的数据结构&#xff0c;分配一块连续的内存来存储。 语法&#xff1a; <数据类型> <数组名>[<数组长度>]; 数据类型&#xff1a;数组内存放的数据类型&#xff0c;如int、char&…

暴雨为IBM发布《可信赖的企业级生成式 AI 白皮书》点赞

2024年 5月 23日&#xff0c;北京&#xff09;&#xff0c;IBM 在北京举行“AI for Business论坛”&#xff0c;与客户、合作伙伴、生态联盟等行业参与者一起&#xff0c;探讨如何将生成式 AI 应用到企业创新和实践当中。会上&#xff0c;中国开源软件推进联盟与 IBM 联合发布《…

LeetCode刷题之HOT100之比特位计数

今天把仙剑三看完了&#xff0c;茂茂割肉让人无法释怀&#xff0c;眼泪止不住的流。长卿和紫萱的分离似乎也意味着重逢&#xff0c;这就是他们的宿命吧。怅然若失的感觉席卷全身&#xff0c;哎&#xff0c;做题吧。 1、题目描述 2、逻辑分析 题目要求将整数从0到此元素&#…

【华为笔试题汇总】2024-05-22-华为春招笔试题-三语言题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新小米近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f49…

vue三级联动组件

背景 项目中经常出现三级下拉框组件的要求&#xff0c;这种组件其中一级发生变化&#xff0c;子级的组件就会发生变化如果这一个组件&#xff0c;单独作为搜索条件使用&#xff0c;很好写&#xff0c;同时作为搜索条件和form回写组件&#xff0c;回显就比较困难 子组件代码 将与…

2.搜索游戏中不可见的数据坐标

内容参考于&#xff1a; 易道云信息技术研究院VIP课 首先一般游戏在设计时会把人物相关的属性放到一起&#xff0c;在 1.搜索游戏中的数据与环境搭建 里也能证实&#xff0c;角色的等级、攻击力、生命值、经验等它们的内存地址都是相差4字节也就是用int类型存储的&#xff0c;…

简单的TCP网络程序:英译汉服务器

一、服务器的初始化 下面介绍程序中用到的socket API,这些函数都在sys/socket.h中。 1.创建套接字 socket()&#xff1a; ⭐参数介绍&#xff1a; socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符;应用程序可以像读写文件一样用read/write在网…

AIGC实践|探索用AI实现小游戏开发全流程

前言&#xff1a; 在上一篇中&#xff0c;我们已经深入探讨了AI工具在动态绘本创作中的应用&#xff0c;体验了AI在创意内容生成上的魅力。本篇文章将带领大家进入一个全新的探索领域——游戏开发。 本文将详细介绍如何利用AI工具探索实现游戏开发的全过程&#xff0c;从概念…

提升代码简洁,MVEL 表达式和责任链设计模式应用实践

导读 本文主要讲解了MVEL表达式和责任链设计模式相结合一起的消息处理解决方案设计、解耦消息处理节点以及方便代码维护扩展。通过“订单拆单消息”的接入作为具体实践案例&#xff0c;简要阐述了MVEL表达式和Apache Chain职责链设计模式应用场景。希望通过本文&#xff0c;读…

【C/C++笔试练习】TCP、IP广播、ARP协议、IP路由器、MAC协议、三次握手、TCP/IP、子网划分年、会抽奖、抄送列表

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;TCP&#xff08;2&#xff09;IP广播&#xff08;3&#xff09;ARP协议&#xff08;4&#xff09;IP路由器&#xff08;5&#xff09;MAC协议&#xff08;6&#xff09;三次握手&#xff08;7&#xff09;TCP/IP&#xf…

Vue 3入门指南

title: Vue 3入门指南 date: 2024/5/23 19:37:34 updated: 2024/5/23 19:37:34 categories: 前端开发 tags: 框架对比环境搭建基础语法组件开发响应式系统状态管理路由配置 第1章&#xff1a;Vue 3简介 1.1 Vue.js的历史与发展 Vue.js由前谷歌工程师尤雨溪&#xff08;Eva…

JVM学习-垃圾回收(三)

System.gc 通过System.gc()或Runtime.getRuntime().gc()的调用&#xff0c;会显示触发Full GC&#xff0c;同时对老年代和方法区进行回收&#xff0c;尝试释放被丢弃对象占用的内存然后System.gc()调用附带一个免责声明&#xff0c;无法保证对垃圾收集器的调用JVM实现者可以通…

第3天 Web源码拓展_小迪网络安全笔记

1.关于web源码目录结构 #数据库配置文件 后台目录 模板目录 数据库目录 1.1数据库配置文件: 1.1就拿wordpress来说,先到官网下载源码:Download – WordPress.org,解压源码之后: 2.2找到目录下名为 wp-config-sample.php的文件,这就是数据库配置文件: 设想: 我们在渗透…

K8S集群再搭建

前述&#xff1a;总体是非常简单的&#xff0c;就是过程繁琐&#xff0c;不过都是些重复的操作 master成员: [controller-manager, scheduler, api-server, etcd, proxy,kubelet] node成员: [kubelet, proxy] master要修改的配置文件有 1. vi /etc/etcd/etcd.conf # 数…

【Linux取经路】一个简单的日志模块

文章目录 一、可变参数的使用二、Log2.1 日志打印2.1.1 时间获取2.1.2 日志分块打印 2.2 打印模式选择2.3 Log 使用样例2.4 Log 完整源码 三、结语 一、可变参数的使用 int sum(int n, ...) {va_list s; // va_list 本质上就是一个指针va_start(s, n); int sum 0;while(n){su…

vue3 + antd-vue@4 a-table单元格合并,rowSpan(行合并),colSpan(列合并)详解, 表头合并详解, 表头自定义详解

一、解释 1、rowSpan 1&#xff09;、行合并 2&#xff09;、当为0时&#xff1a;去掉边框 3&#xff09;、当为1时&#xff1a;不合并 4&#xff09;、大于1的x时&#xff1a;包含当前单元格行合并x个单元格 2、colSpan 1&#xff09;、列合并 2&#xff09;、当为0时&#xf…

反序列化漏洞(JBoss、apache log4、apache Shiro、JWT)Weblogic未授权访问、代码执行、任意上传

1.1什么是反序列化 就是把一个对象变成可以传输的字符串&#xff0c;目的就是为了方便传输。假设&#xff0c;我们写了一个class&#xff0c;这个class里面存有一些变量。当这个class被实例化了之后&#xff0c;在使用过程中里面的一些变量值发生了改变。以后在某些时候还会用到…

CTF网络安全大赛简单web题目:eval

题目来源于&#xff1a;bugku 题目难度&#xff1a;简单 一道简单web的题目 题目源代码&#xff1a; <?phpinclude "flag.php";$a $_REQUEST[hello];eval( "var_dump($a);");show_source(__FILE__); ?> 这个PHP脚本有几个关键部分&#xff0c;但…

Salesforce ADFS SSO 配置

1.set up 中 Certificate and Key Management创建认证 2.setup中Single Sign-On Settings新建SSO&#xff0c;输入必填 3.setup中My Domain Settings设置登录跳转&#xff1a; 最后将Single Sign-On Settings中metadata.xml下载下来给ADFS端使用&#xff1a; 最后效果&#xff…

快手二面准备【面试准备】

快手二面准备【面试准备】 前言版权快手二面准备秋招一面中的问题实习一面中的问题计算机网络和操作系统论坛项目登录注册ThreadLocal代替session存储用户秒杀项目登录注册->阿里验证码->rpcsession为什么改为token实现&#xff0c;redis存储用户信息由binlog的用法->…