如何在Hibernate中维护表的历史记录
為了維護數據庫的歷史記錄或跟蹤數據庫表行的修改,我們創建了一個版本表,其中包含與原始表相同的字段。每當原始表被更改時,我們都會在版本表中創建另一個條目。 因此,對于每個更新查詢,我們都必須在版本表中編寫一個插入查詢。 休眠中有一個模塊可以管理對象的簡單審核,而我們不必自己編寫單獨的插入查詢。
Hibernate Envers提供了內置的機制來維護數據庫中對象的歷史記錄。 Envers是Hibernate的庫,它將幫助我們輕松實現審核功能。 這是由Adam Warski創建的。 從Hibernate 3.5開始,Envers作為Hibernate核心模塊包含在內。 讓我們舉一個例子,說明如何使用Envers維護對象的歷史記錄。
這是Envers的pom依賴關系(版本將與您的休眠核心和實體管理器相同):
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-envers</artifactId> <version>4.0.1.Final</version> </dependency>您必須在hibernate.cfg.xml中配置偵聽器。
<mapping class="com.javaroots.model.User" /><listener class="org.hibernate.envers.event.AuditEventListener" type="post-insert"/><listener class="org.hibernate.envers.event.AuditEventListener" type="post-update"/><listener class="org.hibernate.envers.event.AuditEventListener" type="post-delete"/><listener class="org.hibernate.envers.event.AuditEventListener" type="pre-collection-update"/><listener class="org.hibernate.envers.event.AuditEventListener" type="pre-collection-remove"/><listener class="org.hibernate.envers.event.AuditEventListener" type="post-collection-recreate"/>讓我們以User類為例。 我們要跟蹤用戶字段的更新。 要為用戶對象啟用歷史記錄,我們需要使用@Audited批注。 如果在類級別上使用,則該類中的所有字段都將被視為可審計的,并且任何字段中的更改將在audit table中具有新條目。 如果我們希望某些字段不包含在歷史記錄中,則可以使用@NotAudited批注。 如果更改了NotAudited字段,那么審計表中將沒有任何條目。這是用戶類:
package com.javaroots.model;import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Entity;import org.hibernate.envers.Audited; import org.hibernate.envers.NotAudited;/*** * * @author Abhishek Somani* */ @Entity @Audited public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@Column(length = 20)private String firstName;@Column(length = 20)private String lastName;@Column(length = 20)@NotAuditedprivate String password;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}這是測試類,我們在其中創建用戶表中的條目,然后更新它的field。
package com.javaroots.main;import org.hibernate.Session;import com.javaroots.model.User; import com.javaroots.util.HibernateUtil;public class HibernateTest {public static void main(String[] args) {Session session = HibernateUtil.getSessionFactory().openSession();//one entry will be created in user table //and audit entry created in user_aud tablesession.beginTransaction();User u = new User();u.setFirstName("Amitabh");u.setLastName("bachhan");u.setPassword("God");session.save(u);session.getTransaction().commit();session.beginTransaction();User amitabh = (User)session.get(User.class,1l);amitabh.setFirstName("Abhishek");session.getTransaction().commit();//no entry in audit table if we change password field//because this field is marked as @notAuditedsession.beginTransaction();amitabh = (User)session.get(User.class,1l);amitabh.setPassword("NotGod");session.getTransaction().commit();//get specific revisionAuditReader reader = AuditReaderFactory.get(HibernateUtil.getSessionFactory().openSession());User abhishek = (User) reader.find(User.class, new Long(1), 2);System.out.println(abhishek.getFirstName() + " " + abhishek.getLastName());//get all revisionList versions = reader.getRevisions(User.class, new Long(1));for (Number number : versions) {System.out.print(number + " ");}}}首先,在用戶表中創建一個用戶行。在user_aud中創建一個具有修訂ID和用戶表字段的行。 在revinfo表中使用修訂ID和時間戳創建一行。 這兩個條目由envers自動完成。 這是sql查詢和表結構:
Hibernate: insert intoUser(firstName, lastName, password) values(?, ?, ?) Hibernate: insert intoREVINFO(REVTSTMP) values(?) Hibernate: insert intoUser_AUD(REVTYPE, firstName, lastName, id, REV) values(?, ?, ?, ?, ?) Hibernate: updateUser setfirstName=?,lastName=?,password=? whereid=? Hibernate: insert intoREVINFO(REVTSTMP) values(?) Hibernate: insert intoUser_AUD(REVTYPE, firstName, lastName, id, REV) values(?, ?, ?, ?, ?) Hibernate: updateUser setfirstName=?,lastName=?,password=? whereid=? Hibernate: selectuser_aud0_.id as id4_,user_aud0_.REV as REV4_,user_aud0_.REVTYPE as REVTYPE4_,user_aud0_.firstName as firstName4_,user_aud0_.lastName as lastName4_ fromUser_AUD user_aud0_ whereuser_aud0_.REV=(selectmax(user_aud1_.REV) fromUser_AUD user_aud1_ whereuser_aud1_.REV<=? and user_aud0_.id=user_aud1_.id) and user_aud0_.REVTYPE<>? and user_aud0_.id=? Abhishek bachhan Hibernate: selectuser_aud0_.REV as col_0_0_ fromUser_AUD user_aud0_ cross joinREVINFO defaultrev1_ whereuser_aud0_.id=? and user_aud0_.REV=defaultrev1_.REV order byuser_aud0_.REV ascmysql> select * from user; +----+-----------+----------+---------------+ | id | firstName | lastName | password | +----+-----------+----------+---------------+ | 1 | Amitabh | bachchan | God| +----+-----------+----------+---------------+ 1 row in set (0.03 sec)mysql> select * from user_aud; +----+-----+---------+-----------+----------+ | id | REV | REVTYPE | firstName | lastName | +----+-----+---------+-----------+----------+ | 1 | 1 | 0 | Amitabh | bachchan | +----+-----+---------+-----------+----------+ 1 row in set (0.00 sec)mysql> select * from revinfo; +-----+---------------+ | REV | REVTSTMP | +-----+---------------+ | 1 | 1375956506278| +-----+---------------+ 1 row in set (0.00 sec)mysql> select * from user; +----+-----------+----------+----------------+ | id | firstName | lastName | password | +----+-----------+----------+----------------+ | 1 | Amitabh | bachchan| NotGod | +----+-----------+----------+----------------+ 1 row in set (0.00 sec)mysql> select * from user_aud; +----+-----+---------+-----------+----------+ | id | REV | REVTYPE | firstName | lastName | +----+-----+---------+-----------+----------+ | 1 | 1 | 0 | Amitabh | bachchan | | 1 | 2 | 1 | Abhishek | bachchan| +----+-----+---------+-----------+----------+ 2 rows in set (0.00 sec)mysql> select * from revinfo; +-----+---------------+ | REV | REVTSTMP | +-----+---------------+ | 1 | 1375956506278| | 2 | 1375956506328| +-----+---------------+ 2 rows in set (0.00 sec)- 下載源代碼
翻譯自: https://www.javacodegeeks.com/2013/09/how-to-maintain-history-of-tables-in-hibernate.html
總結
以上是生活随笔為你收集整理的如何在Hibernate中维护表的历史记录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (ddos攻击tcp)
- 下一篇: Servlet上传文件和下载文件示例