天天看點

啟用 Spring Data JPA 審計功能

突然發現 Spring Data JPA 有這麼一個功能,英文是 Auditing

JPA Audit 說明

在spring jpa中,支援在字段或者方法上進行注解@CreatedDate、@CreatedBy、

@LastModifiedDate、@LastModifiedBy,從字面意思可以很清楚的了解,這幾個注解的用處。

@CreatedDate

表示該字段為建立時間時間字段,在這個實體被insert的時候,會設定值

@CreatedBy

表示該字段為建立人,在這個實體被insert的時候,會設定值

@LastModifiedDate、@LastModifiedBy同理。

如何使用審計功能

首先申明實體類,需要在類上加上注解@EntityListeners(AuditingEntityListener.class),其次在application啟動類中加上注解EnableJpaAuditing,同時在需要的字段上加上@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy等注解。

這個時候,在jpa.save方法被調用的時候,時間字段會自動設定并插入資料庫,但是CreatedBy和LastModifiedBy并沒有指派,因為需要實作AuditorAware接口來傳回你需要插入的值。

1.編寫AuditorAware

/**
 * 監聽
 * @CreatedBy
 * @LastModifiedBy
 * 自動注入使用者名
 */
@Configuration
public class UserAuditorAware implements AuditorAware<String> {


    @Override
    public Optional<String> getCurrentAuditor() {
        //TODO: 根據實際情況取真實使用者
        return Optional.of("admin");
    }
}
           

2.在實體類中聲明@EntityListeners和相應的注解

考慮到所有實體都需要聲明,就寫在BaseEntityModel 中

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntityModel  implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -6163675075289529459L;

    @JsonIgnore
    String entityName = this.getClass().getSimpleName();

    @CreatedBy
    String createdBy;

    @LastModifiedBy
    String modifiedBy;
    /**
     * 實體建立時間
     */
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    protected Date dateCreated = new Date();

    /**
     * 實體修改時間
     */
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    protected Date dateModified = new Date();

     #省略getter setter
}
           

3.在Application 中啟用審計@EnableJpaAuditing

@SpringBootApplication
@EnableJpaAuditing
public class Application {
    
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application .class, args);
    }

    /**
     * 測試中如果無法自動識别,可能是包路徑的問題,采用手動聲明bean的方式
     * @return
     */
    @Bean
    public UserAuditorAware setUserAuditorAware(){
        return new UserAuditorAware();
    }
}
           
經過測試如果你的實體類上面的多個字段使用了@CreatedBy這樣的注解,隻會有一個生效,也就是說在一次請求中,隻會被調用一次