审计(Auditing)在 Spring Boot 中指的是自动跟踪和管理应用程序中实体的创建和修改的能力。它是一个强大的功能,提供了有关数据生命周期的宝贵信息,例如谁创建或最后修改了记录以及这些操作发生的时间。这对于需要问责、可追溯性和符合审计标准的应用程序尤其有用。
关键注解
-
@CreatedDate
:用于标记实体类中的字段,该字段应在实体创建时自动填充日期和时间。 -
@LastModifiedDate
:用于标记实体类中的字段,该字段应在实体最后修改时自动更新日期和时间。 -
@CreatedBy
:用于标记实体类中的字段,该字段应填充创建实体的用户。这需要自定义实现来提供用户信息。 -
@LastModifiedBy
:用于标记实体类中的字段,该字段应更新为最后修改实体的用户。这也需要自定义实现来提供用户信息。
实现示例
让我们创建一个简单的 Spring Boot 应用程序,演示如何使用上述注解进行审计。我们将构建一个简单的“用户”实体,跟踪谁创建和修改了它,以及何时进行的操作。
第一步:设置 Spring Boot 应用程序
-
使用 Spring Initializr 创建一个新的 Spring Boot 项目,并添加以下依赖项:
-
Spring Web
-
Spring Data JPA
-
H2 数据库(用于测试)
-
Spring Boot DevTools
-
应用程序结构
以下是应用程序的简要结构:
src
└── main
└── java
└── com
└── example
└── demo
├── DemoApplication.java
├── config
│ └── AuditingConfig.java
├── controller
│ └── UserController.java
├── entity
│ └── User.java
└── repository
└── UserRepository.java
└── resources
├── application.properties
└── data.sql
第二步:定义用户实体
创建一个带有审计注解的 User
实体。
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@CreatedDate
private LocalDateTime createdDate;
@LastModifiedDate
private LocalDateTime lastModifiedDate;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String lastModifiedBy;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDateTime getCreatedDate() {
return createdDate;
}
public void setCreatedDate(LocalDateTime createdDate) {
this.createdDate = createdDate;
}
public LocalDateTime getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(LocalDateTime lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
}
-
@Entity
:指定该类是一个实体,并映射到数据库表。 -
@EntityListeners(AuditingEntityListener.class)
:启用实体的审计功能。 -
@Id
和@GeneratedValue
:指定主键及其生成策略。 -
@CreatedDate
和@LastModifiedDate
:自动设置创建和修改时间戳。 -
@CreatedBy
和@LastModifiedBy
:自动设置创建或最后修改实体的用户。
第三步:启用审计
创建一个配置类以启用 JPA 审计。
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import java.util.Optional;
@Configuration
@EnableJpaAuditing
public class AuditingConfig {
@Bean
public AuditorAware<String> auditorProvider() {
return () -> Optional.of("system"); // You can replace "system" with the actual user
}
}
-
@Configuration
:指定该类包含应用程序的配置。 -
@EnableJpaAuditing
:启用 JPA 审计。 -
auditorProvider()
:提供一个AuditorAware
bean,返回当前用户。在此示例中,它始终返回 “system”。
第四步:为用户实体创建存储库
为 User
实体创建一个存储库接口。
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
@Transactional
@Modifying
@Query("UPDATE User u SET u.name = :name, u.lastModifiedDate = CURRENT_TIMESTAMP, u.lastModifiedBy = :modifiedBy WHERE u.id = :id")
int updateUserName(@Param("id") Long id, @Param("name") String name, @Param("modifiedBy") String modifiedBy);
}
第五步:为用户实体创建控制器
创建一个控制器来处理 HTTP 请求。
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping
public List<User> getAllUsers() {
return userRepository.findAll();
}
@PostMapping
public User createUser(@RequestBody User user) {
return userRepository.save(user);
}
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User userDetails) {
User user = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
user.setName(userDetails.getName());
return userRepository.save(user);
}
// or
// you can native query also
// @PutMapping("/{id}")
// public User updateUser(@PathVariable Long id, @RequestBody User userDetails) {
// int rowsUpdated = userRepository.updateUserName(id, userDetails.getName(), "system");
// if (rowsUpdated == 0) {
// throw new RuntimeException("User not found");
// }
// return userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
// }
}
第六步:使用 Postman 进行测试
-
启动应用程序:运行 Spring Boot 应用程序。
-
创建用户:
-
URL:
POST http://localhost:8080/users
-
Body:
{ "name": "John Doe" }
-
响应:
{ "id": 1, "name": "John Doe", "createdDate": "2023-10-10T10:00:00", "lastModifiedDate": "2023-10-10T10:00:00", "createdBy": "system", "lastModifiedBy": "system" }
-
-
更新用户:
-
URL:
PUT http://localhost:8080/users/1
-
Body:
{ "name": "Jane Doe" }
-
响应:
{ "id": 1, "name": "Jane Doe", "createdDate": "2023-10-10T10:00:00", "lastModifiedDate": "2023-10-10T10:05:00", "createdBy": "system", "lastModifiedBy": "system" }
-
总结
通过使用 Spring Boot 的审计功能,你可以轻松地跟踪实体的创建和修改时间以及操作者。这对于需要记录数据变更历史的应用场景非常有用,例如合规性审计、数据追踪等。通过结合 @CreatedDate
、@LastModifiedDate
、@CreatedBy
和 @LastModifiedBy
注解,你可以实现强大的审计功能,而无需编写大量代码。
没有回复内容