小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Spring Data JPA教程:審計(一)

 jackeyqing 2018-11-25

提到審計,首先從腦海中蹦出的就是審計日志,記錄了實體版本的修改信息。但是實現(xiàn)審計日志是個既耗時又復雜的任務(wù),幸運的是,大部分時候我們都不需要

然而,還是有些經(jīng)常碰到的問題:
* 實體什么時候被創(chuàng)建和修改?
* 誰創(chuàng)建和修改了這個實體?

Spring Data JPA的審計功能可以幫助我們解決這兩個問題,下面我們介紹一下怎樣通過Spring Data JPA提供的審計功能記錄實體的創(chuàng)建和修改時間

一開始,我們需要先寫一個返回當前日期和時間的服務(wù),定義一個DateTimeService接口

為什么使用接口而不是類實現(xiàn)這個服務(wù)呢,原因如下:

  • 我們想創(chuàng)建兩個不同的實現(xiàn)類
    • 第一個實現(xiàn)返回當前的日期和時間
    • 第二個實現(xiàn)用于測試,每次返回相同的日期和時間
  • 如果是個產(chǎn)品應用,其他組件也會通過接口進行調(diào)用

DateTimeService接口的聲明只有一個方法:

  • getCurrentDateAndTime(),該方法返回一個ZonedDateTime對象

DateTimeService接口代碼如下:

import java.time.ZonedDateTime;

public interface DateTimeService {

    ZonedDateTime getCurrentDateAndTime();
}

CurrentTimeDateTimeService實現(xiàn)了DateTimeService接口,getCurrentDateAndTime()的實現(xiàn)只是簡單的返回了當前時間

CurrentTimeDateTimeService實現(xiàn)如下:

import java.time.ZonedDateTime;

public class CurrentTimeDateTimeService implements DateTimeService {

    @Override
    public ZonedDateTime getCurrentDateAndTime() {
        return ZonedDateTime.now();
    }
}

下面我們看看怎樣將我們寫的service與Spring Data JPA進行集成

Spring Data JPA使用DateTimeProvider接口獲取日期和時間,所以我們只要實現(xiàn)這個接口就可以將我們的service集成到Spring中

步驟如下:

  1. 創(chuàng)建一個AuditingDateTimeProvider類,實現(xiàn)DateTimeProvider接口
  2. 添加一個DateTimeService類型的字段,通過構(gòu)造函數(shù)注入
  3. 實現(xiàn)getNow()方法,通過DateTimeService對象獲取當前日期和時間,返回一個GregorianCalendar對象

AuditingDateTimeProvider實現(xiàn)如下:

import org.springframework.data.auditing.DateTimeProvider;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class AuditingDateTimeProvider implements DateTimeProvider {

    private final DateTimeService dateTimeService;

    public AuditingDateTimeProvider(DateTimeService dateTimeService) {
        this.dateTimeService = dateTimeService;
    }

    @Override
    public Calendar getNow() {
        return GregorianCalendar.from(dateTimeService.getCurrentDateAndTime());
    }
}

下一步是對ApplicationContext進行配置,先創(chuàng)建一個DateTimeService類型的bean,在configuration class(XML configuration file)中聲明。通過如下步驟配置bean:

  1. 創(chuàng)建currentTimeDateTimeService()方法返回一個CurrentTimeDateTimeService對象
  2. 加上@Bean注解
  3. 加上@Profile注解,值設(shè)置為Profiles.APPLICATION,確保應用啟動時bean被創(chuàng)建

相應的配置類如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;

@Configuration
@ComponentScan("net.petrikainulainen.springdata.jpa")
@Import({WebMvcContext.class, PersistenceContext.class})
public class ExampleApplicationContext {

    @Profile(Profiles.APPLICATION)
    @Bean
    DateTimeService currentTimeDateTimeService() {
        return new CurrentTimeDateTimeService();
    }
}

然后,將我們的DateTimeProvider bean配置到Spring Data JPA,通過更改事例程序的持久化層配置來實現(xiàn):

  1. 創(chuàng)建dateTimeProvider()方法返回一個DateTimeProvider對象,構(gòu)造函數(shù)傳入我們的DateTimeService對象
  2. 返回一個AuditingAwareDateTimeProvider對象
  3. 加上@Bean注解
  4. 加上@EnableJpaAuditing注解,dataTimeProviderRef的值設(shè)置為dateTimeProvider

相應的PersistenceContext配置如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaAuditing(dateTimeProviderRef = "dateTimeProvider")
@EnableJpaRepositories(basePackages = {
"net.petrikainulainen.springdata.jpa.todo"
})
@EnableTransactionManagement
class PersistenceContext {

    @Bean
    DateTimeProvider dateTimeProvider(DateTimeService dateTimeService) {
        return new AuditingDateTimeProvider(dateTimeService);
    }
}

下面修改實體類,要實現(xiàn)如下需求:

  1. 確保creationTime在第一次存儲時被設(shè)置
  2. 確保modificationTime在第一次存儲和每次更新時被設(shè)置

通過下面步驟就能實現(xiàn)上述目標:

  1. 為creationTime字段加上@CreatedDate注解
  2. 為modificationTime字段加上@LastModifiedDate注解
  3. 為實體類加上@EntityListeners注解,將值設(shè)置為AuditingEntityListener.class

相應的Todo實體類修改如下:

import org.hibernate.annotations.Type;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
import java.time.ZonedDateTime;
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "todos")
final class Todo {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "creation_time", nullable = false)
    @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")
    @CreatedDate
    private ZonedDateTime creationTime;

    @Column(name = "description", length = 500)
    private String description;

    @Column(name = "modification_time")
    @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentZonedDateTime")
    @LastModifiedDate
    private ZonedDateTime modificationTime;

    @Column(name = "title", nullable = false, length = 100)
    private String title;

    @Version
    private long version;
}

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多