[SpringBoot]自定义注解@AutoFill,实现公共字段自动填充(避免重复对时间属性初始化

对于时间属性,如createTime、updateTime在进行插入、修改操作时都要一个个初始化处理,过于麻烦。

可以自定义注解@AutoFill作用于INSERT,UPDATE操作方法上,再自定义切面类,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值。

涉及知识点:枚举、注解、AOP、反射

目录

1.自定义注解@AutoFill, 用于标示某个方法需要进行功能字段自动填充处理

2.在Mapper层对应insert、update方法上加上注解@AutoFill 

3.自定义切面,实现公共字段自动填充处理逻辑


 

老办法,缺点:过于重复和麻烦 

f70a5dfc6b814f26858b12527979df4f.png

好方法:公共字段自动填充

1.自定义注解@AutoFill, 用于标示某个方法需要进行功能字段自动填充处理

35f97158fdcc433f9764c65c3d3f32a2.png 

自定义注解:AutoFill

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 {// 枚举数据库类型:UPDATE INSERT 用于标示自动填充的类型OperationType value();
}

自定义枚举类型:OperationType

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

2.在Mapper层对应insert、update方法上加上注解@AutoFill 

026ceabe5cf14f4cae50585c0fb5ca98.png

1600c05e83fa4352b103d0076db0091e.png

3.自定义切面,实现公共字段自动填充处理逻辑

 ①定义切入点,即统一拦截加入了AutoFill 注解的方法

 ②编写前置通知,进行公共字段自动填充

  • 获取到当前被拦截的方法上的数据库操作类型

  • 获取到当前被拦截的方法的参数--实体对象

  • 准备赋值的数据

  • 根据当前不同的操作类型,为对应的属性通过反射来赋值

自定义切面类:AutoFillAspect

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 org.aspectj.lang.JoinPoint;
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("开始进行公共字段自动填充...");//1. 获取到当前被拦截的方法上的数据库操作类型MethodSignature signature = (MethodSignature)joinPoint.getSignature(); //方法签名对象AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); //获得方法上的对象OperationType operationType = 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 (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();}}}
}

公共字段填充常量类:AutoFillConstant

/*** 公共字段自动填充相关常量*/
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";
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫获取百度的图片

一. 爬虫的方式: 主要有2种方式: ①ScrapyXpath (API 静态 爬取-直接post get) ②seleniumXpath (点击 动态 爬取-模拟) ScrapyXpath XPath 是 Scrapy 中常用的一种解析器,可以帮助爬虫定位和提取 HTML 或 XML 文档中的数据。 Scrapy 中使用 …

ctfshow——信息搜集

文章目录 web 1web 2web 3web 4web 5web 6web 7web 8web 9web 10web 11web 12web 13web 14web 15web 16web 17web 18web 19web 20 web 1 题目提示开发注释未及时删除。 直接右键查看源代码。 web 2 在这关我们会发现:1)无法使用右键查看源代码&…

【亚马逊云科技】自家的AI助手 - Amazon Q

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…

Neuro Contamination - Cyberpunk Gaming Music Futuristic Glitchy Sci-fi

无论是展示赛博朋克未来的电影场景,还是介绍高科技武器,你的音乐选择都至关重要。这首曲子的灵感来自科幻小说,旨在让你的观众想象未来的感觉。 潜在用例:科幻游戏、赛博朋克游戏、电影预告片、动作场景和产品广告。 非常适合充…

爆肝整理,接口测试+为什么要做接口测试总结,策底贯通...

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

【SpringBoot+dubbo+zk】实现服务之间rpc通信

0)前置准备&#xff0c;我们使用zk作为注册中心&#xff0c;先启动zk&#xff0c;也就是2181端口。 1)父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http…

现有网络模型的使用及修改(VGG16为例)

VGG16 修改默认路径 import os os.environ[TORCH_HOME] rD:\Pytorch\pythonProject\vgg16 # 下载位置太大了&#xff08;140多G&#xff09;不提供直接下载 train_set torchvision.datasets.ImageNet(root./data_image_net, splittrain, downloadTrue, transformtorchvis…

GPDB - 高可用 - 流复制状态

GPDB - 高可用 - 流复制状态 GPDB的高可用基于流复制&#xff0c;通过FTS进行自动故障切换。自动故障切换需要根据primary-mirror流复制的各种状态进行判断。本节就聊聊primary-mirror流复制的各种状态。同样适用于PgSQL 1、WalSndState typedef enum WalSndState {WALSNDSTATE…

本地部署 Ollama

本地部署 Ollama 0. Ollama 能帮我们做什么1. 下载 Ollama2. 安装 Ollama3. 使用 Ollama4. Ollama 和 Langchain 的集成 0. Ollama 能帮我们做什么 在本地启动并运行大型语言模型。 运行 Llama 2、Code Llama 和其他模型。自定义并创建自己的。 1. 下载 Ollama 访问 https:…

【数据仓库与联机分析处理】数据仓库工具Hive

目录 一、Hive简介 &#xff08;一&#xff09;什么是Hive &#xff08;二&#xff09;优缺点 &#xff08;三&#xff09;Hive架构原理 &#xff08;四&#xff09;Hive 和数据库比较 二、MySQL的安装配置 三、Hive的安装配置 1、下载安装包 2、解压并改名 3、配置环…

ubuntu创建pytorch-gpu的docker环境

文章目录 安装docker创建镜像创建容器 合作推广&#xff0c;分享一个人工智能学习网站。计划系统性学习的同学可以了解下&#xff0c;点击助力博主脱贫( •̀ ω •́ )✧ 使用docker的好处就是可以将你的环境和别人的分开&#xff0c;特别是共用的情况下。本文介绍了ubuntu环境…

由浅入深理解C#中的事件

目录 本文较长&#xff0c;给大家提供了目录&#xff0c;可以直接看自己感兴趣的部分。 前言有关事件的概念示例​ 简单示例​ 标准 .NET 事件模式​ 使用泛型版本的标准 .NET 事件模式​ 补充总结 参考前言 前面介绍了C#中的委托&#xff0c;事件的很多部分都与委托…

Vue知识总结-中

VUE-生命周期 生命周期概述 生命周期也常常被称为生命周期回调函数/生命周期函数/生命周期钩子生命周期是Vue在关键时刻帮我们调用的一些特殊名称的函数生命周期函数的名字不能更改,但函数的具体内容是由我们程序员自己编写的生命周期函数中的this指向是vm或组件实例对象 生命周…

OpenCV | 光流估计

光流估计 光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”&#xff0c;根据各个像素点的速度的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪 高度恒定&#xff1a;同一点随着时间的变化&#xff0c;其亮度不会发生改变。小运动&…

Hive实战:网址去重

文章目录 一、实战概述二、提出任务三、完成任务&#xff08;一&#xff09;准备数据1、在虚拟机上创建文本文件2、上传文件到HDFS指定目录 &#xff08;二&#xff09;实现步骤1、启动Hive Metastore服务2、启动Hive客户端3、基于HDFS数据文件创建Hive外部表4、利用Hive SQL实…

JavaScript基础(24)_dom查询练习(一)

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><link rel"stylesheet" href"../browser_default_style/reset.css"><title>dom查询练习一</title><style>.text {widt…

uniapp 微信小程序跳转外部链接

一、背景&#xff1a; 开发小程序时&#xff0c;跳转到内部路径通常会使用&#xff1a;uni.navigateTo&#xff0c;uni.redirectTo&#xff0c;uni.reLaunch&#xff0c;uni.switchTab等方法&#xff0c;可以跳转到pages.json中已经注册的页面 uni.navigateTo(OBJECT) | uni-…

架构模式:分片

什么是分片&#xff1f; 分片是一种数据库架构模式&#xff0c;涉及将数据库划分为更小、更快、更易于管理的部分&#xff0c;称为分片。每个分片都是一个不同的数据库&#xff0c;这些分片共同构成了整个数据库。分片对于管理大型数据库特别有用&#xff0c;可以显着提高性能…

部署上传漏洞的靶场环境upload-labs

1、工具介绍 upload-labs是一个使用php语言编写的&#xff0c;专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关&#xff0c;每一关都包含着不同上传方式。 upload-labs靶场开源地址&#xff1a;&#xff1a;https://…

代码随想录day60:贪心算法|84.柱状图中最大的矩形

84. Largest Rectangle in Histogram 进行优化&#xff0c;如果我们想获得left就给他left即可&#xff0c;我们只需要在求宽度的时候用到left,而没必要修改原数组。 所以给栈插入一个虚拟索引-1 思考过程&#xff1a; left应该为多少呢&#xff1f; 首先确定left是什么&#…