pkslow.com 南瓜慢说

  • AllArticles
  • Container
  • Spring
  • Life
  • Cloud
  • Collections
  • About
  • GitHub

  • Search
Terraform101 English Terraform Middleware config Go Private Kubernetes pkslow Test HTTPS Redis Docker Mac Plan Stream MongoDB Spring DevOps JVM String Map Set List Performance Email Springboot JavaCollections ArrayList Java

Spring Data JPA的Audit功能,审计数据库的变更

Created on: 2021-01-15 | Category: Springboot | 0 | View: 1203

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 Security的Context来获取登陆用户的名字,当然可以有其它方案,如获取请求头的某个字段等。

注意注解@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


参考资料:

Auditing with JPA, Hibernate, and Spring Data JPA


Code for all: GitHub

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

file

Recommendations:
Cloud Native
Terraform
Container: Docker/Kubernetes
Spring Boot / Spring Cloud
Https
如何制定切实可行的计划并好好执行

  • Author 作者: LarryDpk 南瓜慢说
  • Link 链接: https://www.pkslow.com/archives/spring-data-jpa-audit
  • 版权声明: 本博客所有文章除特别声明外,不可转载!
# Terraform101 # English # Terraform # Middleware # config # Go # Private # Kubernetes # pkslow # Test # HTTPS # Redis # Docker # Mac # Plan # Stream # MongoDB # Spring # DevOps # JVM # String # Map # Set # List # Performance # Email # Springboot # JavaCollections # ArrayList # Java
Terraform101 English Terraform Middleware config Go Private Kubernetes pkslow Test HTTPS Redis Docker Mac Plan Stream MongoDB Spring DevOps JVM String Map Set List Performance Email Springboot JavaCollections ArrayList Java
Java怎么从这四个位置读取配置文件Properties(普通文件系统-classpath-jar-URL)
Intellij IDEA同一个项目(窗口)多个代码仓库
  • Contents
  • Site Overview
南瓜慢说

南瓜慢说

多年Java开发,主要专注后端技术:Java/Spring/Springboot/微服务/大数据等。

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

241 Posts
9 Categories
30 Tags
RSS
0%
© 2020 — 2022 南瓜慢说 pkslow The WebSite keeping alive:   粤ICP备20036375号