使用envers記錄數(shù)據(jù)變更版本

hibernate的envers模塊提供了一整套機(jī)制可以用來記錄數(shù)據(jù)的變更仰剿。這里簡單介紹一下全陨。

1.自動(dòng)配置

@SpringBootApplication
@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
@EnableJpaAuditing(auditorAwareRef = "auditorAwareImpl")
public class EnversDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(EnversDemoApplication.class, args);
    }
}

這里配置@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)表示開啟envers模塊。

2.Audited注解

@Entity
@Audited
public class Book extends AuditableEntity{

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

    private String title;

    private String author;

    private String description;

    private long price;

    private boolean valid;

    // getter and setter
}

使用@Audited標(biāo)注一下這個(gè)實(shí)體類需要審計(jì)甚颂。

繼承RevisionRepository

public interface BookDao extends RevisionRepository<Book, Long, Integer>,JpaRepository<Book, Long> {
}

通過繼承RevisionRepository獲取查找revisions的查詢方法蜜猾,主要如下:

@NoRepositoryBean
public interface RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>> {
    Revision<N, T> findLastChangeRevision(ID var1);

    Revisions<N, T> findRevisions(ID var1);

    Page<Revision<N, T>> findRevisions(ID var1, Pageable var2);

    Revision<N, T> findRevision(ID var1, N var2);
}

這里的N是指變更版本號(hào)的類型,一般Integer夠用振诬,如果覺得不夠用可以改為Long類型蹭睡。這里的T就是實(shí)體類。ID就是實(shí)體類的主鍵類型贷揽。

查詢變更

經(jīng)過以上配置之后棠笑,就可以正常記錄變更的每個(gè)版本了,可以通過如下方法來查詢禽绪,比如:

Revisions<Integer,Book> revision = bookDao.findRevisions(id);
List<Revision<Integer,Book>> data = revision.getContent();

這里的id為實(shí)體的id

revision的表結(jié)構(gòu)

hibernate默認(rèn)以實(shí)體類后綴_AUD來記錄每個(gè)變更的版本蓖救,比如

-- ----------------------------
--  Table structure for book_aud
-- ----------------------------
DROP TABLE IF EXISTS "public"."book_aud";
CREATE TABLE "public"."book_aud" (
    "id" int8 NOT NULL,
    "rev" int4 NOT NULL,
    "revtype" int2,
    "author" varchar(255) COLLATE "default",
    "description" varchar(255) COLLATE "default",
    "price" int8,
    "title" varchar(255) COLLATE "default",
    "valid" bool
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."book_aud" OWNER TO "postgres";

-- ----------------------------
--  Primary key structure for table book_aud
-- ----------------------------
ALTER TABLE "public"."book_aud" ADD PRIMARY KEY ("id", "rev") NOT DEFERRABLE INITIALLY IMMEDIATE;

-- ----------------------------
--  Foreign keys structure for table book_aud
-- ----------------------------
ALTER TABLE "public"."book_aud" ADD CONSTRAINT "fk2u9iq76nh69r6f989ae7xft9" FOREIGN KEY ("rev") REFERENCES "public"."revinfo" ("rev") ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE;

如果想改表后綴的話洪规,可以通過org.hibernate.envers.audit_table_suffix的屬性進(jìn)行配置。里頭的rev字段表示revision的版本號(hào)循捺,一般全局遞增斩例。revtype字段表示操作類型,0表示新增从橘,1表示更新念赶,2表示刪除。

另外還有一個(gè)表是revinfo恰力,記錄每個(gè)變更的版本號(hào)和時(shí)間:

-- ----------------------------
--  Table structure for revinfo
-- ----------------------------
DROP TABLE IF EXISTS "public"."revinfo";
CREATE TABLE "public"."revinfo" (
    "rev" int4 NOT NULL,
    "revtstmp" int8
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."revinfo" OWNER TO "postgres";

-- ----------------------------
--  Primary key structure for table revinfo
-- ----------------------------
ALTER TABLE "public"."revinfo" ADD PRIMARY KEY ("rev") NOT DEFERRABLE INITIALLY IMMEDIATE;

自定義revision entity

如果默認(rèn)的envers的實(shí)現(xiàn)不滿足你的要求的話叉谜,使用@RevisionEntity注解,替換@Audited踩萎,然后自定義listener停局,比如

@Entity
@RevisionEntity( ExampleListener.class )
public class ExampleRevEntity extends DefaultRevisionEntity {
    private String username;

    public String getUsername() { return username; }
    public void setUsername( String username ) { this.username = username; }
}
public class ExampleListener implements RevisionListener {

    public void newRevision( Object revisionEntity ) {
        ExampleRevEntity exampleRevEntity = ( ExampleRevEntity ) revisionEntity;
        Identity identity =
            (Identity) Component.getInstance( "org.jboss.seam.security.identity" );

        exampleRevEntity.setUsername( identity.getUsername() );
    }
}

具體的這里就不細(xì)講了,具體可以參考hibernate香府。

doc

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末董栽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子企孩,更是在濱河造成了極大的恐慌锭碳,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勿璃,死亡現(xiàn)場離奇詭異擒抛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蝗柔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門闻葵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來民泵,“玉大人癣丧,你說我怎么就攤上這事≌蛔保” “怎么了胁编?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鳞尔。 經(jīng)常有香客問我嬉橙,道長,這世上最難降的妖魔是什么寥假? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任市框,我火速辦了婚禮,結(jié)果婚禮上糕韧,老公的妹妹穿的比我還像新娘枫振。我一直安慰自己喻圃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布粪滤。 她就那樣靜靜地躺著斧拍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪杖小。 梳的紋絲不亂的頭發(fā)上肆汹,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機(jī)與錄音予权,去河邊找鬼昂勉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛扫腺,可吹牛的內(nèi)容都是我干的硼啤。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼斧账,長吁一口氣:“原來是場噩夢啊……” “哼谴返!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咧织,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤嗓袱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后习绢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渠抹,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年闪萄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了梧却。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡败去,死狀恐怖放航,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情圆裕,我是刑警寧澤广鳍,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站吓妆,受9級(jí)特大地震影響赊时,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜行拢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一祖秒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦竭缝、人聲如沸狐胎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽握巢。三九已至,卻和暖如春松却,著一層夾襖步出監(jiān)牢的瞬間暴浦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工晓锻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留歌焦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓砚哆,卻偏偏與公主長得像独撇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子躁锁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容