Web项目中公共字段的自动填充

问题分析

一般在Web项目中,很多数据库表都有公共的字段,如下:

序号字段名含义数据类型
1create_time创建时间datetime
2create_user创建人idbigint
3update_time修改时间datetime
4update_user修改人idbigint

而针对于这些字段,我们的赋值方式为:

1). 在新增数据时, 将createTime、updateTime 设置为当前时间, createUser、updateUser设置为当前登录用户ID。

2). 在更新数据时, 将updateTime 设置为当前时间, updateUser设置为当前登录用户ID。

以前,在我们的项目中处理这些字段都是在每一个业务方法中进行赋值操作,如下:

新增员工方法:

	/**
     * 新增员工
     *
     * @param employeeDTO
     */
    public void save(EmployeeDTO employeeDTO) {
        //.......................
		//
        //设置当前记录的创建时间和修改时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());

        //设置当前记录创建人id和修改人id
        employee.setCreateUser(BaseContext.getCurrentId());//目前写个假数据,后期修改
        employee.setUpdateUser(BaseContext.getCurrentId());
		///
        employeeMapper.insert(employee);
    }

编辑员工方法:

	/**
     * 编辑员工信息
     *
     * @param employeeDTO
     */
    public void update(EmployeeDTO employeeDTO) {
       //........................................
	   ///
        employee.setUpdateTime(LocalDateTime.now());
        employee.setUpdateUser(BaseContext.getCurrentId());
       ///

        employeeMapper.update(employee);
    }

如果都按照上述的操作方式来处理这些公共字段, 需要在每一个业务方法中进行操作, 编码相对冗余、繁琐,那能不能对于这些公共字段在某个地方统一处理,来简化开发呢?

答案是可以的,我们使用AOP切面编程,实现功能增强,来完成公共字段自动填充功能。

实现思路

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

序号字段名含义数据类型操作类型
1create_time创建时间datetimeinsert
2create_user创建人idbigintinsert
3update_time修改时间datetimeinsert、update
4update_user修改人idbigintinsert、update

实现步骤:

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

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

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

若要实现上述步骤,需掌握以下知识

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

代码开发

首先需要定义一个枚举类型OperationType

/**
 * 数据库操作类型
 */
public enum OperationType {

    /**
     * 更新操作
     */
    UPDATE,

    /**
     * 插入操作
     */
    INSERT
}

自定义注解 AutoFill

/**
 * 用于标识某个方法需要自动填充字段
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
    //指定数据库的操作类型:UPDATE INSERT
    OperationType value();
}

自定义切面 AutoFillAspect

/**
 * 自定义切面,实现公共字段的自动填充
 * TODO AOP(1)
 */
@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){
            //为四个公共字段赋值
            try {
                Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
                Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser", Long.class);
                Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setCreateTime.invoke(entity,now);
                setCreateUser.invoke(entity,currentId);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else if (operationType == OperationType.UPDATE) {
            //为两个公共字段赋值
            try {
                Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
                Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
                setUpdateTime.invoke(entity,now);
                setUpdateUser.invoke(entity,currentId);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }


    }
}

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

分别在新增和修改方法添加@AutoFill()注解

@Mapper
public interface EmployeeMapper {


    /**
     * 新增员工
     * @param employee
     */
    @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 insert(Employee employee);



    /**
     * 根据id动态修改属性
     * @param employee
     */
    @AutoFill(value = OperationType.UPDATE)
    void update(Employee employee);

}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频技术助力智慧城市一网统管:视频资源整合与智能化管理

随着信息技术的飞速发展,智慧城市已成为现代城市发展的重要方向。在智慧城市建设中,一网统管作为城市管理的重要策略,通过整合各类信息资源,实现资源的优化配置和问题的快速响应。其中,视频技术作为一网统管场景中的关…

【Linux系统】动态库和静态库 动态库加载

认识动态库静态库 我们有没有使用过库呢?-- 用过c、c的标准库 c的各种函数,c的各种STL容器,我们使用他们内部必须得有具体实现。 Linux: .so(动态库) .a(静态库) Windows: .dll(动态库) .lib(静态库) 库是拿来给别人使用的,所…

sd调试记录:

现象:SDIO读取TF卡,1bit模式正常(一切操作都正常),4bit模式无法读取: 比如在使用函数f_opendir(&DirInf, SDPath)、f_open(&SDFile, path, FA_CREATE_ALWAYS | FA_WRITE)函数时会出现错…

局部静态变量实现的单例存在多个对象

文章目录 背景测试代码运行测试尝试打开编译器优化进一步分析 背景 业务中出现日志打印失效&#xff0c;发现是因为管理日志对象的单例在运行过程中存在了多例的情况。下面通过还原业务场景来分析该问题。 测试代码 /* A.h */ #ifndef CALSS_A #define CALSS_A#include <…

如何从 Windows 11/10/8.1/8/7 恢复已删除的视频

意外删除了视频或格式化了 SD 卡/硬盘&#xff1f;没有备份已删除的视频&#xff1f;别担心&#xff0c;我们有解决方案来恢复 Windows 11、10 中已删除的视频并处理这种糟糕的情况。 但在了解如何恢复已删除的视频和视频恢复应用程序之前&#xff0c;请知道 Windows 会为您提…

IDEA与通义灵码的智能编程之旅

1 概述 本文主要介绍在IDEA中如何安装和使用通义灵码来助力软件编程,从而提高编程效率,创造更大的个人同企业价值。 2 安装通义灵码 2.1 打开IDEA插件市场 点击IDEA的设置按钮,下拉选择Plugins,如下: 2.2 搜索通义灵码 在搜索框中输入“通义灵码”,如下: 2.3 安…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01—短信/邮件/异常/MD5

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…

rsyslog日志转发

前言 Rsyslog可用于接受来自各种来源(本地和网络)的输入&#xff0c;转换它们&#xff0c;并将结果输出到不同&#xff08;通过模板和filter过滤&#xff09;的目的地&#xff08;目录文件中&#xff09; rsyslog是一个开源工具&#xff0c;被广泛用于Linux系统以通过TCP/UDP…

树莓派5安装冬瓜HAOS教程

原文来自瀚思彼岸和hasshome 一、安装前准备 &#xff08;1&#xff09;软件 1、树莓派烧录软件Imager 2、冬瓜HAOS镜像 &#xff08;2&#xff09;硬件 1、树莓派5 2、TF卡&#xff08;SanDisk Extreme PRO 64GB U3 A2 V30 4k&#xff09; 3、读卡器 4、键盘和鼠标 5、显…

550kg级大载重长航时无人机直升机技术详解

550kg级大载重长航时无人机直升机&#xff0c;作为一种高性能的无人机系统&#xff0c;具备了多项先进的技术特点&#xff0c;以满足高海拔、高寒等复杂环境下的应用需求。这些无人机直升机通常具备高载重、长航时、强适应性、高可靠性和良好的任务拓展性。 设备由无人直升机平…

ctfshow-web入门-文件上传(web151-web160)

目录 1、web151 2、web152 3、web153 4、web154 5、web155 6、web156 7、web157 8、web158 9、web159 10、web160 1、web151 试了下前端只能传 png 后缀的 将一句话木马改成 png 后缀&#xff0c;上传后用 burpsuite 抓包 绕过前端检测后&#xff0c;改回 php 后缀&am…

(南京观海微电子)——MOS管原理及应用区别

MOS管&#xff1a; 全称为金属氧化物半导体场效应管&#xff08;Metal Oxide Semiconductor Field Effect Transistor&#xff09;&#xff0c;也被称为MOSFET&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor&#xff09;。它是一种半导体器件&#xff0c;常用…

[数据结构] 基于选择的排序 选择排序堆排序

标题&#xff1a;[数据结构] 基于选择的排序 选择排序&&堆排序 水墨不写bug &#xff08;图片来源于网络&#xff09; 目录 &#xff08;一&#xff09;选择排序 实现&#xff1a;(默认从小到大排序) 优化后实现方法&#xff1a; &#xff08;二&#xff09;堆排序…

latex英文转中文word,及一些latex相关工具分享

前言&#xff1a;想要转换latex生成的英文pdf文件为中文word文件 一、主要步骤 1、文字翻译&#xff1a;直接使用谷歌翻译等辅助将英文翻译成中文即可&#xff1b; 2、图片&#xff1a; 使用latex时一般保存的.png&#xff0c;.bmp格式图片可以直接插入word, 但是.eps或者 .p…

基于Android Studio零食工坊

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 用户 可以浏览商品 &#xff0c; 查询商品 &#xff0c; 加入购物车 &#xff0c; 结算商品 &#xff0c; 查看浏览记录 &#xff0c; 修改密码 &#xff0c; 修改个人信息 &#xff0c; 查询订单 管理员 能够实现商品的…

AIGC专栏12——EasyAnimateV3发布详解 支持图文生视频 最大支持960x960x144帧视频生成

AIGC专栏12——EasyAnimateV3发布详解 支持图&文生视频 最大支持960x960x144帧视频生成 学习前言项目特点生成效果相关地址汇总项目主页Huggingface体验地址Modelscope体验地址源码下载地址 EasyAnimate V3详解技术储备Diffusion Transformer (DiT)Hybrid Motion ModuleU-V…

分布式整合

一、分布式架构介绍 什么是分布式系统 分布式系统指一个硬件或软件组件分布在不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进行通信和协调的系统。 通俗的理解&#xff0c;分布式系统就是一个业务拆分成多个子业务&#xff0c;分布在不同的服务器节点&#xff0…

测试环境:使用OpenSSL生成证书并配置Https

文章目录 需求1、安装OpenSSL1.1、安装包下载1.2、安装&#xff08;以window 64位为例&#xff09;1.3、配置环境变量&#xff08;非必须&#xff09; 2、生成证书2.1、新建文件夹2.2、生成根证书2.2.1、生成私钥2.2.2、生成根证书&#xff0c;并且自签名 2.3、服务端证书生成2…

JDBC的基本认识

前提 在了解和学习JDBC之前&#xff0c;大家 已经学习过 java语言 和数据库的基本知识了&#xff0c;今天这篇博客的核心&#xff0c;就是告诉大家 &#xff0c;jdbc 是连接java编译器和数据库&#xff0c;是使用java对数据库进行操作的。 正文 JDBC简介 概念 JDBC的本质 1…

解决微信读书和Apple Books导入epub电子书不显示图片的问题

title: 解决微信读书和Apple Books导入epub电子书不显示图片的问题 tags: 个人成长 categories:杂谈 最近找到一本很喜欢的书的电子版的epub版&#xff0c;发现无论是导入微信读书&#xff0c;还是Apple家的Books, 都无法正常显示图片。 于是我用calibre打开epub电子书&#x…