Spring Data是一个建立在spring框架之上的模块,用于简化数据库事务。它提供了各种接口和注释,以便于开发。Spring 数据使用@Repository注释,这是 Spring 框架提供的注释的构造型之一,用于创建与数据库访问相关的 bean。我们需要使用@EnableJpaRepositories注释启用弹簧数据。如果我们使用基于 XML 的命名空间,那么我们可以使用以下配置:
<?xml version="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.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-envers</artifactId>
</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