使用Spring Data JPA实现审计功能,记录创建人、创建时间、最后修改时间和最后修改人

本文主要是介绍使用Spring Data JPA实现审计功能,记录创建人、创建时间、最后修改时间和最后修改人,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 前言
    • 实现方式
      • 基于`AuditorAware`接口实现审计功能
        • 启用JPA审计功能
        • 定义实体类
        • 实现`AuditorAware`接口
      • 基于自定义监听器实现审计功能
        • 启用JPA审计功能
        • 定义实体类
        • 定义自定义监听器类
    • 总结

前言

近日心血来潮想做一个开源项目,目标是做一款可以适配多端、功能完备的模板工程,包含后台管理系统和前台系统,开发者基于此项目进行裁剪和扩展来完成自己的功能开发。

本项目为前后端分离开发,后端基于Java21SpringBoot3开发,后端使用Spring SecurityJWTSpring Data JPA等技术栈,前端提供了vueangularreactuniapp微信小程序等多种脚手架工程。

在项目中每条数据在创建或修改的时候,我想记录创建人,创建时间,最后修改人,最后修改时间等审计信息。如果每次都手动赋值,代码会变得冗长,显得很不优雅。Spring Data JPA为我们提供了审计功能,可以在执行创建或修改操作时自动为审计信息赋值。

本文将介绍两种实现方式,关于SpringBoot项目如何整合Spring Data JPA,请参阅https://blog.csdn.net/kingslave1/article/details/135661646

实现方式

使用Spring Data JPA实现审计功能,主要涉及以下注解:

  • @EnableJpaAuditing,启用JPA审计功能开关。
  • @EntityListeners,可以监听实体对象的增删改查操作,调用监听器中设置的回调方法。
  • @CreatedBy,创建人,执行insert操作时自动赋值。
  • @CreatedDate,创建日期,执行insert操作时自动赋值。
  • @LastModifiedBy,最后修改人,执行insertupdate操作时自动赋值。
  • @LastModifiedDate,最后修改时间,执行insertupdate操作时自动赋值。

基于AuditorAware接口实现审计功能

启用JPA审计功能

定义一个配置类Bean,启用Spring Data JPA和审计功能,也可以直接main方法所在类上直接添加@EnableJpaRepositories@EntityScan@EnableJpaAuditing注解。

/*** Spring Data JPA Bean配置* 启用Jpa,扫描指定包下的Repository类和指定包下的实体类*/
@Configuration
@EnableJpaRepositories(basePackages = {"com.demo.data.repo"})
@EntityScan(basePackages = "com.demo.data.model")
@EnableJpaAuditing
public class JpaConfig {
}
定义实体类

以定义一个用户类SysUser为例,为其添加@EntityListeners({AuditingEntityListener.class})注解,在其审计信息属性上添加@CreatedBy等注解。

@Getter
@Setter
@Entity
@EntityListeners({AuditingEntityListener.class})
public class SysUser implements Serializable {/*** ID,唯一标识列,使用主键自增策略*/@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;/*** 创建时间*/@CreatedDateprivate LocalDateTime createdTime;/*** 最后修改时间*/@LastModifiedDateprivate LocalDateTime lastModifiedTime;/*** 创建人ID*/@CreatedByprivate Long creatorId;/*** 最后修改人ID*/@LastModifiedByprivate Long lastModifierId;    /*** 用户名*/@Column(unique = true)private String username;/*** 密码*/private String password;/*** 电话*/private String phone;
}
实现AuditorAware接口

我们需要定义一个AuditorAware接口的实现类,并将其注册为Bean。

实现AuditorAware<T>接口需要传递类型参数,这个参数应使用创建人(creatorId)最后修改人(lastModifierId)属性的类型,在实体类SysUsercreatorIdlastModifierId的类型是Long,则此处泛型参数也应该为Long

@Component
public class AuditorAwareImpl implements AuditorAware<Long> {/*** 返回当前用户ID,insert和update操作会调用该方法自动赋值*/@Overridepublic Optional<Long> getCurrentAuditor() {// 获取当前用户Id,具体获取逻辑请自行实现Long userId = 1L;return Optional.ofNullable(userId);}
}

至此,审计功能开发完成,可调用SysUser类的Repository接口执行创建或修改操作来测试是否开发成功。

基于自定义监听器实现审计功能

基于AuditorAware接口实现审计功能虽然简单,但也存在不适用的场景,例如创建人属性不仅要记录创建人的用户ID,还需要记录创建人的用户名时;或者开发者希望仅在insert操作时执行某些操作。
针对上述场景,可以考虑使用自定义实体操作监听器的方式实现,实现步骤如下。

启用JPA审计功能

定义一个配置类Bean,启用Spring Data JPA和审计功能,也可以直接main方法所在类上直接添加@EnableJpaRepositories@EntityScan@EnableJpaAuditing注解。

/*** Spring Data JPA Bean配置* 启用Jpa,扫描指定包下的Repository类和指定包下的实体类*/
@Configuration
@EnableJpaRepositories(basePackages = {"com.demo.data.repo"})
@EntityScan(basePackages = "com.demo.data.model")
@EnableJpaAuditing
public class JpaConfig {
}
定义实体类

以定义一个用户类SysUser为例,为其添加@EntityListeners({AuditingEntityListener.class, CustomEntityAuditingListener.class})注解,在其审计信息属性上添加@CreatedBy等注解。
与1.2一节中给出的实体类相比,新增了creatorlastModifier两个属性,@EntityListeners注解中多了一个CustomEntityAuditingListener,在下一节中笔者将给出CustomEntityAuditingListener的实现代码。

@Getter
@Setter
@Entity
@EntityListeners({AuditingEntityListener.class, CustomEntityAuditingListener.class})
public class SysUser implements Serializable {/*** ID,唯一标识列,使用主键自增策略*/@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;/*** 创建时间*/@CreatedDateprivate LocalDateTime createdTime;/*** 最后修改时间*/@LastModifiedDateprivate LocalDateTime lastModifiedTime;/*** 创建人ID*/@CreatedByprivate Long creatorId;/*** 创建人用户名*/private String creator;/*** 最后修改人ID*/@LastModifiedByprivate Long lastModifierId;  /*** 最后修改人用户名*/  private Long lastModifier;  /*** 用户名*/@Column(unique = true)private String username;/*** 密码*/private String password;/*** 电话*/private String phone;
}
定义自定义监听器类

自定义监听器会用到以下几种注解,可以监听数据库操作的不同时机。

  • @PostLoad,实体对象查询之后
  • @PrePersist,实体对象保存之前
  • @PostPersist,实体对象保存之后
  • @PreUpdate,实体对象修改之前
  • @PostUpdate,实体对象修改之后
  • @PreRemove,实体对象删除之前
  • @PostRemove,实体对象删除之后

以下是CustomEntityAuditingListener类的实现代码,使用了@PrePersist@PreUpdate两个注解。

public class CustomEntityAuditingListener {@PrePersistprivate void prePersist(BaseEntity entity) {// 获取当前用户,具体获取逻辑请自行实现SysUser current = new SysUser();entity.setCreatorId(current.getId());entity.setCreator(current.getUsername());entity.setLastModifierId(current.getId());entity.setLastModifier(current.getUsername());}@PreUpdateprivate void preUpdate(BaseEntity entity) {// 获取当前用户,具体获取逻辑请自行实现SysUser current = new SysUser();entity.setLastModifierId(current.getId());entity.setLastModifier(current.getUsername());}
}

至此,审计功能开发完成,可调用SysUser类的Repository接口执行创建或修改操作来测试是否开发成功。

总结

本文介绍了两种使用Spring Data JPA实现审计功能的方法,实现AuditorAware接口和自定义实体操作监听器,可以在创建或修改数据时自动为审计信息赋值,减少了冗长的手动赋值代码,如有错误,还望批评指正。

在后续实践中我也是及时更新自己的学习心得和经验总结,希望与诸位看官一起进步。

这篇关于使用Spring Data JPA实现审计功能,记录创建人、创建时间、最后修改时间和最后修改人的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/621382

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1