Spring Data是一个建立在spring框架之上的模块,用于简化数据库事务。它提供了各种接口和注释,以便于开发。Spring 数据使用@Repository注释,这是 Spring 框架提供的注释的构造型之一,用于创建与数据库访问相关的 bean。我们需要使用@EnableJpaRepositories注释启用弹簧数据。如果我们使用基于 XML 的命名空间,那么我们可以使用以下配置:
- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:jpa="http://www.springframework.org/schema/data/jpa"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/data/jpa
- http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
- <jpa:repositories base-package="com.example.repositories"/>
- beans>
或者,如果我们没有实现 Spring 数据接口,Spring 数据也提供@RepositoryDefinition注释。
在某些情况下,我们曾经跨应用程序编写基本接口,对于这些接口,我们不想为它创建 Spring bean,Spring 数据为同一事物提供了@NoRepositoryBean注释以排除类来创建 bean。
JPA 提供程序没有明确提供审计,但我们可以使用生命周期事件来实现审计。
JPA 将为事务提交前提供@PrePersist、@PreUpdate和@PreRemove注释,并为事务提交后提供@PostPersist、@PostUpdate@PostRemove注释。
我们可以在实体级别使用这些注释,也可以将这些注释方法编写在单独的类中,并且可以在类级别作为实体侦听器提供。
- public class AuditListener {
-
- @PrePersist
- private void beforeInsert(Object object) { ... }
-
- @PreUpdate
- private void beforeUpdate(Object object) { ... }
-
- @PreRemove
- private void beforeDelete(Object object) { ... }
-
- @PostPersist
- private void AfterInsert(Object object) { ... }
-
- @PostUpdate
- private void AfterUpdate(Object object) { ... }
-
- @PostRemove
- private void AfterDelete(Object object) { ... }
-
- }
- And Entity class will look like below:
- @EntityListeners(AuditListener.class)
- @Entity
- public class SampleEntity {
- // methods
- }
如果我们想使用 JPA 查询实体修订,我们还需要创建审计实体,需要为其实现所有 CRUD 操作。
如果我们使用 Spring Data JPA,它将为所有操作提供一个事件侦听器,它还引入了一个存储库实现 RevisionRepository 接口来查询审计数据。
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-data-jpaartifactId>
- dependency>
- <dependency>
- <groupId>org.springframework.datagroupId>
- <artifactId>spring-data-enversartifactId>
- dependency>
如果我们使用 spring boot,则需要上述依赖项,否则我们需要检查两个库的兼容版本。
Spring Data Envers 为引导 Envers 相关的 bean 提供了@EnableJpaAuditing注释,而 AuditingEntityListener 是我们所有常见审计功能的抽象监听器。
在类级别添加此侦听器,对于那些我们想要启用审计的实体,类似的 JPA 实现,但侦听器类将由 Spring Data Envers 提供。
- @EntityListeners(AuditingEntityListener.class)
- @Entity
- public class SampleEntity {
- // methods
- }
对于 Spring 数据存储库接口,实现用于获取修订的 RevisionRepository 接口。
如果我们使用的是Spring安全性,我们还可以使用AuditAware界面跟踪用户所做的更改。
为了跟踪用户更改,需要使用 @LastModifiedBy,@CreatedBy 注释 2 个实体字段以跟踪更改。
这些字段的值将由 AuditAware 接口实现设置。
我们需要创建一个 AuditAware 的 bean,它是这个接口的实现,并提供对@EnableJpaAuditing注释的 bean 引用作为参数。
- class SpringSecurityAuditorAware implements AuditorAware < UserDetails > {
- publicUserDetailsgetCurrentAuditor() {
-
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-
- if (authentication == null || !authentication.isAuthenticated()) {
- return null;
- }
-
- return ((UserDetails) authentication.getPrincipal()).getUser();
- }
- }
- @Configuration
- @EnableJpaAuditing(auditorAwareRef = "auditorProvider ")
- public class AuditConfig {
- @Bean
- AuditorAware < String > auditorProvider() {
- return new SpringSecurityAuditorAware();
- }
- }
与@LastModifiedBy类似,@CreatedBy注释,我们有@CreatedDate、@LastModifiedDate注释来跟踪创建和修改日期。
最佳做法是将所有这些公共字段移动到基实体类,并且每个实体类都必须扩展此基实体类,并且需要使用@MappedSuperClass批注对其进行批注。
JPA 规范不会直接提供审计的方式,但我们可以通过事件侦听器来实现,我们需要在每个实体级别编写大量代码来实现。
Spring Data Envers 是通过使用注释消除大部分重复代码的库之一。Spring Data Envers提供了一个RevisionRepository接口,用于查询实体的审计历史记录,如果我们在应用程序中使用Spring安全性,我们还可以使用AuditorAware界面跟踪特定用户所做的更改。
参考源码:GitHub - allwaysoft/thymeleaf-pagination-sorting-envers