AOP如何实现公共字段自动填充

在数据库表的设计中主键id,创建时间create_time,更新时间update_time都是必须的字段,根据实际的需求可能还需要用到创建用户名create_username,和更新用户名update_username这两个字段。

其中的create_time、update_time、create_username、update_username都是属于是表的公共字段,如果每次在进行插入或者更新操作时都要手动赋值是很繁琐的。

通过AOP实现公共字段自动填充,只需给mapper层中的对应方法加上注解即可。

依赖

<!--AOP起步依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

OperateType枚举

枚举数据库操作类型

/*** @Description: 数据库操作类型* @Author: 翰戈.summer* @Date: 2023/11/17* @Param:* @Return:*/
public enum OperateType {//插入操作INSERT,//更新操作UPDATE}

AutoFill注解

AutoFill注解,用于标识需要进行公共字段自动填充的方法。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @Description: 注解,用于标识需要进行公共字段自动填充的方法* @Author: 翰戈.summer* @Date: 2023/11/18* @Param:* @Return:*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {/*** 数据库操作类型,INSERT插入操作,UPDATE更新操作*/OperateType value();}

AutoFillAspect切面类

切入点一定要写对,这里用到的是前置通知,拦截mapper层接口的方法,获取方法参数进行公共字段填充。

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;/*** @Description: 切面类,实现公共字段自动填充* @Author: 翰戈.summer* @Date: 2023/11/19* @Param:* @Return:*/
@Aspect
@Component
public class AutoFillAspect {/*** @Description: 切入点* @Author: 翰戈.summer* @Date: 2023/11/19* @Param:* @Return: void*/@Pointcut("execution(* com.demo.mapper.*.*(..)) && @annotation(com.demo.annotation.AutoFill)")public void autoFillPointcut() {}/*** @Description: 前置通知,进行公共字段自动填充* @Author: 翰戈.summer* @Date: 2023/11/19* @Param: JoinPoint* @Return: void*/@Before("autoFillPointcut()")public void autoFill(JoinPoint joinPoint) {//获取方法签名对象MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();//获取注解对象AutoFill autoFill = methodSignature.getMethod().getAnnotation(AutoFill.class);//获取数据库操作类型OperateType operateType = autoFill.value();//获取拦截方法实体类对象参数Object[] args = joinPoint.getArgs();if (args == null || args.length == 0) {return;}Object entity = args[0];//获取填充数据String username = BaseContext.getContext();// 当前用户名LocalDateTime now = LocalDateTime.now();// 当前时间//为插入操作填充数据if (operateType == OperateType.INSERT) {try {Method setCreateUsername = entity.getClass().getDeclaredMethod("setCreateUsername", String.class);Method setUpdateUsername = entity.getClass().getDeclaredMethod("setUpdateUsername", String.class);Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);setCreateUsername.invoke(entity, username);setUpdateUsername.invoke(entity, username);setCreateTime.invoke(entity, now);setUpdateTime.invoke(entity, now);} catch (Exception ex) {throw new RuntimeException();}}//为更新操作填充数据if (operateType == OperateType.UPDATE) {try {Method setUpdateUsername = entity.getClass().getDeclaredMethod("setUpdateUsername", String.class);Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);setUpdateUsername.invoke(entity, username);setUpdateTime.invoke(entity, now);} catch (Exception ex) {throw new RuntimeException();}}}
}

BaseContext上下文

线程局部变量,用于存放用户名,便于在AutoFillAspect切面类中获取。

/*** @Description: 线程局部变量* @Author: 翰戈.summer* @Date: 2023/11/17* @Param:* @Return:*/
public class BaseContext {public static ThreadLocal<String> threadLocal = new ThreadLocal<>();public static void setContext(String context) {threadLocal.set(context);}public static String getContext() {return threadLocal.get();}public static void removeContext() {threadLocal.remove();}
}

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

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

相关文章

go-carbon v2.2.14 发布,轻量级、语义化、对开发者友好的 Golang 时间处理库

carbon 是一个轻量级、语义化、对开发者友好的 golang 时间处理库&#xff0c;支持链式调用。 目前已被 awesome-go 收录&#xff0c;如果您觉得不错&#xff0c;请给个 star 吧 github.com/golang-module/carbon gitee.com/golang-module/carbon 安装使用 Golang 版本大于…

Docker的学习笔记

1.1 docker的介绍 1.2 docker的一次安装 //如果是root用户&#xff0c;不加sudo也行curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add -echo deb https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/ buster stable…

RabbitMq整合Springboot超全实战案例+图文演示+源码自取

目录 介绍 简单整合 简单模式 定义 代码示例 work模式 定义 代码示例 pubsub模式 定义 代码示例 routing模式 定义 代码示例 top模式 定义 代码 下单付款加积分示例 介绍 代码 可靠性投递示例 介绍 代码 交换机投递确认回调 队列投递确认回调 ​延迟消…

clickhouse -- clickhouse解析复杂JSON数组

举例 - 查数据 select _id,doctorId,patientId,diagnosisList from patient_disease final where diagnosisList is not null limit 3;- 解析数组 SELECT _id,doctorId,patientId,visitParamExtractRaw(diagnosisList,diagnosisName) FROM patient_disease final where _id …

柱状展示当中 ,如何给每个位置加多个项的办法

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>双柱修改</title> <script src"https://cdn.staticfile.org/Chart.js/3.9.1/chart.js"></script> </head> <body><canvas i…

Android进阶——更节电的后台任务JobScheduler 机制使用详解

文章大纲 引言一、JobScheduler 机制概述二、JobSchedulerService 服务1、触发JobSchedulerService 的启动2、JobSchedulerService 对象的构造2.1、使用system_server进程的主线程Looper初始化了JobHandler2.2、创建了JobSchedulerService 的对应Binder服务端2.3、创建了持久化…

vue中使用echarts实现省市地图绘制,根据数据在地图上显示柱状图信息,增加涟漪特效动画效果

一、实现效果 使用echarts实现省市地图绘制根据数据在地图显示柱状图根据数据显示数据&#xff0c;涟漪效果 二、实现方法 1、安装echarts插件 npm install echarts --save2、获取省市json数据 https://datav.aliyun.com/portal/school/atlas/area_selector 通过 阿里旗下…

openbabel 安装 生成指纹方法

今日踩坑小结&#xff1a; openbabel 安装&#xff1a; 可以装&#xff0c;但是得在 Linux 环境下&#xff0c;win 环境装会报错&#xff08;安装不会报错&#xff0c;但是生成指纹的时候会&#xff09; 指纹&#xff1a; 在下面这个链接里&#xff0c;官方给出了命令行调用 o…

MinGW是什么,怎么安装

MinGW&#xff08;Minimalist GNU for Windows&#xff09;是一个用于Windows平台的GCC&#xff08;GNU Compiler Collection&#xff09;编译器的移植版本。它可以让开发者在Windows环境下使用GCC来编译和链接C、C等语言的程序。 MinGW提供了一套开源的编译工具&#xff0c;包…

Doris 数据导入一:Broker Load 方式

1.Doris导入数据的方式总结 导入(Load)功能就是将用户的原始数据导入到 Doris 中。导入成功后,用户即可通过 Mysql 客户端查询数据。为适配不同的数据导入需求,Doris 系统提供了6种不同的导入方式。每种导入方式支持不同的数据源,存在不同的使用方式(异步,同步)。 所有…

如何在 Ubuntu 22.04中安装 Docker Compose

1 安装 pip # 下载get-pip.py脚本 wget https://bootstrap.pypa.io/pip/3.10/get-pip.py 或者 # 下载最新版本 curl https://bootstrap.pypa.io/get-pip.py --output get-pip.py# 为 Python 3 安装 pip sudo python3 get-pip.py2 安装 Pip 后&#xff0c;运行以下命令安装 Doc…

数据结构基础(带头节点的双向循环链表)

完整代码 DLinkList.hDLinkList.ctest.c DLinkList.h #pragma once #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int ElemType;// SList - 单链表 // DList - 双链表 // 带头节点的双向循环链表 - 最优链表结构&#xff0c;任意位置…

Spinnaker 基于 jenkins 触发部署

jenkins job 触发部署 将 Jenkins 设置为 Spinnaker 中的持续集成 (CI) 系统可让您使用 Jenkins 触发管道、向管道添加 Jenkins 阶段或向管道添加脚本阶段。 前置要求&#xff1a; 已在kubernetes中部署spinnaker已准备可用的jenkins实例 启用 jenkins触发器 官方文档&…

TZOJ 1379 C语言合法标识符

答案&#xff1a; #include <stdio.h> #include <string.h> int main() {char arr[60];int n 0, i 0, num 0, flag;scanf("%d", &n);getchar(); //读取回车键while (n--) //循环N次{gets(arr);num strlen(arr); //num为字符串长度flag 1; …

利用ElementUI配置商品的规格参数

商品有不同的规格组合&#xff0c;自动生成对应规格的所有组合&#xff0c;并设置该规格的图片、价格、库存数据。 <template><div class"sku-list"><template v-if"!disabled"><div class"sku-list-head"><el-but…

开启新零售时代,引领消费革命

开启新零售时代&#xff0c;引领消费革命 新零售的魅力在于它将线上线下融合&#xff0c;打破了传统零售的界限。以往&#xff0c;消费者需要亲自前往实体店面购物&#xff0c;但如今他们可以通过电子商务平台随时随地进行购物。这种便捷的消费方式不仅节省了时间和精力&#x…

【带头学C++】----- 九、类和对象 ---- 9.2 构造函数

目录 9.2 构造函数 9.2.1 构造函数的概述 9.2.2 构造函数定义方法&#xff08;初始化构造函数&#xff09; 9.2.3 提供构造函数的影响 9.2 构造函数 以下是一些C引入构造函数的原因&#xff1a; 初始化对象&#xff1a;构造函数允许在创建对象时立即初始化该对象的成员变量…

如何快速了解一家公司?

在炒股过程中&#xff0c;我们想要了解一家公司是否具有投资价值&#xff0c;需要查看和阅读很多公司的相关资料。股民们自行去查询往往会花费很多的时间精力&#xff0c;所以专业的炒股软件一般都会给股民提供这些现成的资料。 在金斗云智投APP内&#xff0c;进入到个股详情页…

【Node.js】笔记梳理 7 - mongoose

写在最前&#xff1a;跟着视频学习只是为了在新手期快速入门。想要学习全面、进阶的知识&#xff0c;需要格外注重实战和官方技术文档&#xff0c;文档建议作为手册使用 系列文章 【Node.js】笔记整理 1 - 基础知识【Node.js】笔记整理 2 - 常用模块【Node.js】笔记整理 3 - n…

mac修改默认shell为bash

1. 打开系统偏好设置 2. 点击用户群组 3. 按住ctrl&#xff0c;点击用户名 4. 点击高级选项&#xff0c;修改登录shell 参考&#xff1a;在 Mac 上将 zsh 用作默认 Shell - 官方 Apple 支持 (中国)