我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶!

1 数据库审计

数据库审计是指当数据库有记录变更时,可以记录数据库的变更时间和变更人等,这样以后出问题回溯问责也比较方便。对于审计表记录的变更可以两种方式,一种是建立一张审计表专门用于记录,另一种是在数据库增加字段。本文所讨论的是第二种方案。

那如何在新增、修改、删除的时候同时增加记录呢?如果每张表都单独记录,代码就会显得很冗余。更好的方式应该是做切面或者事件监听,当数据有变更时统一进行记录。

2 Spring Data JPA审计

Spring Data JPA为我们提供了方便的Audit功能,通过四个注解来标记字段:

(1) @CreatedBy: 创建人

(2) @CreatedDate: 创建时间

(3) @LastModifiedBy: 最后修改人

(4) @LastModifiedDate: 最后修改时间

接下来我们来看看怎么使用。

2.1 项目准备

通过Docker启动PostgreSQL数据库:

docker run -itd \
--name pkslow-postgres \
-e POSTGRES_DB=pkslow \
-e POSTGRES_USER=pkslow \
-e POSTGRES_PASSWORD=pkslow \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-p 5432:5432 \
postgres:10

引入相关依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

Spring Security不是必须的,这里使用它来获取用户名。配置的用户为:

spring.security.user.name=pkslow
spring.security.user.password=123456

2.2 创建实体父类

其实父类不是必须的,你可以在每个想Audit的实体类进行配置,但比较麻烦,不如创建一个父类,再让想审计的子类都继承它:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Auditable<U> {
@CreatedBy
@Column(name = "created_by")
private U createdBy; @CreatedDate
@Column(name = "created_date")
private Date createdDate; @LastModifiedBy
@Column(name = "last_modified_by")
private U lastModifiedBy; @LastModifiedDate
@Column(name = "last_modified_date")
private Date lastModifiedDate;
// getter
//setter
}

@MappedSuperclass可以让其它子实体类继承相关的字段和属性;

@EntityListeners设置监听类,会对新增修改进行回调处理。

有了父类之后,子类就简单了:

@Entity
@Table(name = "pkslow_users")
public class User extends Auditable<String> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
private String name;
private String email;
private String country;
private String website;
//getter setter
}

2.3 如何获取名字

数据总是被修改的,我们要提供一个获取修改人名字的接口,配置如下:

@Configuration
@EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class JpaAuditingConfiguration { @Bean
public AuditorAware<String> auditorProvider() {
return () -> {
String username = "system";
SecurityContext context = SecurityContextHolder.getContext();
if (context != null) {
Authentication authentication = context.getAuthentication();
if (authentication != null) {
username = authentication.getName();
}
} String result = username;
return Optional.ofNullable(result);
};
}
}

这里配置的是通过Spring SecurityContext来获取登陆用户的名字,当然可以有其它方案,如获取请求头的某个字段等。

注意注解@EnableJpaAuditing开启了审计功能。

2.4 测试

我们通过一个Controller来新增数据,看看会有什么效果:

@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping
public User save(@RequestBody User user) {
return userRepository.save(user);
}
}

通过curl命令来测试如下:

$ curl 'http://localhost:8088/user' -X POST \
> -H 'Content-Type: application/json' \
> -H 'Authorization:Basic cGtzbG93OjEyMzQ1Ng==' \
> -d '{
> "name":"larry",
> "email":"admin@pkslow.com",
> "country":"China",
> "website":"www.pkslow.com"
> }'
{"createdBy":"pkslow","createdDate":"2021-01-15T15:08:47.035+0000","lastModifiedBy":"pkslow","lastModifiedDate":"2021-01-15T15:08:47.035+0000","userId":7,"name":"larry","email":"admin@pkslow.com","country":"China","website":"www.pkslow.com"}

查看数据库,已经生成了审计记录:

3 总结

代码请查看:https://github.com/LarryDpk/pkslow-samples


欢迎关注微信公众号<南瓜慢说>,将持续为你更新...

多读书,多分享;多写作,多整理。

Spring Data JPA的Audit功能,审计数据库的变更的更多相关文章

  1. Spring Data JPA(官方文档翻译)

    关于本书 介绍 关于这本指南 第一章 前言 第二章 新增及注意点 第三章 项目依赖 第四章 使用Spring Data Repositories 4.1 核心概念 4.2 查询方法 4.3 定义rep ...

  2. Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!

    前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...

  3. 实例对比 hibernate, spring data jpa, mybatis 选型参考

    原文: 最近重构以前写的服务,最大的一个变动是将mybatis切换为spring data jpa,切换的原因很简单,有两点:第一.它是spring的子项目能够和spring boot很好的融合,没有 ...

  4. 【Spring Data 系列学习】Spring Data JPA @Query 注解查询

    [Spring Data 系列学习]Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作.但同时 ...

  5. Springboot 系列(十)使用 Spring data jpa 访问数据库

    前言 Springboot data jpa 和 Spring jdbc 同属于 Spring开源组织,在 Spring jdbc 之后又开发了持久层框架,很明显 Spring data jpa 相对 ...

  6. 使用Spring Boot 和Spring Data JPA访问mysql数据库

    在Spring中使用JdbcTemplate是一种基本的数据访问方式,但是仍然需要较多的代码,为了解决这些大量枯燥的数据操作语句,我们可以使用ORM框架,比如:Hibernate,通过整合Hibern ...

  7. Spring Boot使用Spring Data Jpa对MySQL数据库进行CRUD操作

    只需两步!Eclipse+Maven快速构建第一个Spring Boot项目 构建了第一个Spring Boot项目. Spring Boot连接MySQL数据库 连接了MySQL数据库. 本文在之前 ...

  8. Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  9. SpringBoot入门 (五) 数据库访问之spring data jpa

    本文记录学习使用spring data jpa访问数据库 一 什么是Spring Data JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java ...

随机推荐

  1. 逆向工程初步160个crackme-------1

    放假在家学习的效率真的很低,看完看雪加密解密的前两章就迫不及待的找了几个crackme练习一下,顺便熟悉ollydbg的使用. 工具:exeinfope(查壳工具),ollydbg(2.10版) 1. ...

  2. 2020 ICPC EC Final西安现场赛游记

    也不知道从何说起,也不知道会说些什么,最想表达的就是很累很累. 从第一天去的时候满怀希望,没什么感觉甚至还有一些兴奋.到后来一直在赶路,感觉很疲惫,热身赛的时候觉得马马虎虎,导致热身赛被咕.然后教练就 ...

  3. 风变编程(Python自学笔记)第10关-工作量计算器

    1.%f的意思是格式化字符串为浮点型,%.1f的意思是格式化字符串为浮点型,并保留1位小数. 2.向上取整:ceil() 使用ceil()方法时需要导入math模块,例如 1 >>> ...

  4. 28.HashSet

    4.HashSet集合 4.1HashSet集合概述和特点[应用] 底层数据结构是哈希表 不能保证存储和取出的顺序完全一致 不可以存储重复元素 没有索引,不能使用普通for循环遍历 4.2HashSe ...

  5. too much recursion

    今天在火狐浏览器上调试swagger接口遇到一个浏览器报错: too much recursion 刚开始以为接口出问题了,但是调试之后发现,后台有数据返回,往下一拉,看到了差不多两千多条数据,一下子 ...

  6. golang:三次握手四次挥手总结

    TCP的三次握手 所谓三次握手 Three-Way Handshake 是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立.好比两个人在打电话: 当连接被建立或被终止,交换的报 ...

  7. JMeter四种参数化方式

    JMeter参数化是指把固定的数据动态化,这样更贴合实际的模拟用户请求,比如模拟多个不同账号.JMeter一共有四种参数化方式,分别是: CSV Data Set Config Function He ...

  8. gdb 调试,当发现程序退出,需要定位程序退出位置时。

    在进入gdb后设置,执行下面语句 handle SIGSEGV nopass handle SIGSEGV nostop 执行程序,触发问题,gdb侧执行c 故障出现时,执行bt,显示堆栈调用.

  9. centos下如何查看命令由哪个包提供

    今天在使用centos进行端口查看的时候发现系统没有netstat命令 yum安装发现并没有同名的包 经过一番查阅 学习到了 yum whatprovides/provides [commandNam ...

  10. python使用多线程备份数据库

    前言:在日常服务器运维工作中,备份数据库是必不可少的,刚工作那会看到公司都是用shell脚本循环备份数据库,到现在自己学习python语言后,利用多进程多线程相关技术来实现并行备份数据库,充分利用服务 ...