posts - 156,  comments - 601,  trackbacks - 0
          測試版本:
           Hibernate 3.3.2
           Hibernate envers 1.2.2.ga-hibernate-3.3

          介紹:
          Hibernate Envers目的是根據對實體的設置,提供記錄執行數據變更歷史的功能(數據變更版本)。它實現原理是通過對Hibernate的操作事件監聽并根據
          基于Annoatation的配置來記錄修改數據的內容。

          1. 配置方法

          基于Spring的配置內容如下:

          1.1 配置Envers事件監聽器
           1     <bean id="sessionFactory"
           2         class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
           3         <property name="dataSource">
           4             <ref local="dataSource" />
           5         </property>
           6         <property name="eventListeners">
           7             <map>
           8                 <entry key="post-insert" value-ref="enversEventListener" />
           9                 <entry key="post-update" value-ref="enversEventListener" />
          10                 <entry key="post-delete" value-ref="enversEventListener" />
          11                 <entry key="post-collection-recreate" value-ref="enversEventListener" />
          12                 <entry key="pre-collection-remove" value-ref="enversEventListener" />
          13                 <entry key="pre-collection-update" value-ref="enversEventListener" />
          14             </map>
          15         </property>        
          16         <property name="configLocation" value="classpath:conf/hibernate.cfg.xml" />
          17     </bean>
          18 
          19      <bean name="enversEventListener" class="org.hibernate.envers.event.AuditEventListener" />


          所有的監聽事件都由 AuditEventListener 來處理。


          1.2 配置 Envers相關屬性
             
              org.hibernate.envers.audit_table_prefix  配置數據修改記錄表名的前綴規則  默認值:空
              org.hibernate.envers.audit_table_suffix  配置數據修改記錄表名的后綴規則  默認值:_AUD
              org.hibernate.envers.revision_field_name  配置數據修改記錄表版本號字段名  默認值: REV
              org.hibernate.envers.revision_type_field_name  配置數據修改記錄表修改類型字段名  默認值: REVTYPE  . 0表示新增加,1修改 2刪除
             
              org.hibernate.envers.revision_on_collection_change 配置是否支持關聯表修改時記錄修改記錄  默認值:true
              org.hibernate.envers.do_not_audit_optimistic_locking_field 配置是否不對樂觀鎖字段修改時記錄修改記錄,即使用(@Version)字段  默認值:true
              org.hibernate.envers.store_data_at_delete 配置是否在刪除操作時,只保存id值還是全部的值。 默認值:false 只記錄id
              org.hibernate.envers.default_schema    配置數據修改記錄表的schema 默認值:null
              org.hibernate.envers.default_catalog  配置數據修改記錄表的catalog 默認值:null


          屬性配置方法: hibernate.cfg.xml

              <property name="org.hibernate.envers.audit_table_suffix">_Audit</property>
              <property name="org.hibernate.envers.audit_table_prefix">log_</property>
              <property name="org.hibernate.envers.revision_field_name">rev</property>
              <property name="org.hibernate.envers.revision_type_field_name">revtype</property>
              <property name="org.hibernate.envers.revision_on_collection_change">true</property>
              <property name="org.hibernate.envers.do_not_audit_optimistic_locking_field">true</property>
              <property name="org.hibernate.envers.store_data_at_delete">true</property>
              <property name="org.hibernate.envers.default_schema"></property>
              <property name="org.hibernate.envers.default_catalog"></property>


          使用hibernate auto-generate功能,自動創建數據修改記錄表
           在hibernate.cfg.xml 加入以下內容
                  <property name="hibernate.hbm2ddl.auto">update</property>
                 
                 
                 
          2. 代碼開發
              Envers目前提供的常用幾類API如下:       
             
              @Audited 標記該Entity類或屬性支持數據修改記錄支持。 Target(value={java.lang.annotation.ElementType.TYPE,java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD}
              @NotAudited 標記該屬性不支持數據修改記錄支持 Target(value={java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD})
                 
             
              @RevisionEntity 實現為數據修改記錄表保存其它自定義內容實現。如修改時間,操作人等。該類必須是一個實體類,會將數據存放一個單獨表中。
              @RevisionTimestamp    記錄修改時間 必須配合 @RevisionEntity使用
            @RevisionNumber 修改記錄表的版本id 通常是配置成主鍵
                 
                 
          2.1 演示示例
          有一個student實體。添了@Audited設置
           1 @Audited
           2 @Entity
           3 public class Student implements Serializable {
           4     /**
           5      * serial Version UID
           6      */
           7     private static final long serialVersionUID = 478336850989535510L;
           8 
           9     private int age;
          10 
          11     private int id;
          12     
          13     private String name;
          14     
          15     private byte[] data;
          16     
          17     private int version;
          18 
          19     /**
          20      * @return the data
          21      */
          22     @NotAudited
          23     @Column(name="data", length=5000)
          24     public byte[] getData() {
          25         return data;
          26     }
          27 
          28     /**
          29      * @param data the data to set
          30      */
          31     public void setData(byte[] data) {
          32         this.data = data;
          33     }
          34 
          35     @Override
          36     public String toString() {
          37         return new ToStringBuilder(this).append("age", age).append("id", id)
          38                 .append("name", name).toString();
          39     }
          40 
          41     @Column(name="age")
          42     public int getAge() {
          43         return age;
          44     }
          45 
          46     @Id
          47     @GeneratedValue
          48     public int getId() {
          49         return id;
          50     }
          51     
          52     @Column(name="name", length=100)
          53     public String getName() {
          54         return name;
          55     }
          56 
          57     public void setAge(int age) {
          58         this.age = age;
          59     }
          60 
          61     public void setId(int id) {
          62         this.id = id;
          63     }
          64 
          65     public void setName(String name) {
          66         this.name = name;
          67     }
          68 
          69     /**
          70      * @return the version
          71      */
          72     @Version
          73     public int getVersion() {
          74         return version;
          75     }
          76 
          77     /**
          78      * @param version the version to set
          79      */
          80     public void setVersion(int version) {
          81         this.version = version;
          82     }
          83 }   

          生成對應的數據修改記錄表sql腳本為:
          1 CREATE TABLE `log_student_audit` (
          2   `id` int(11NOT NULL,
          3   `rev` int(11NOT NULL,
          4   `revtype` tinyint(4DEFAULT NULL,
          5   `age` int(11DEFAULT NULL,
          6   `name` varchar(100DEFAULT NULL,
          7   PRIMARY KEY (`id`,`rev`),
          8   KEY `FKD8A956DCF6C3C1B7` (`rev`)
          9 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

          為 Student修改記錄內容擴展保存一些其它內容實現如下:
          增加     SimpleRevEntity 實體類
           1 @Entity
           2 @RevisionEntity(SimpleListener.class)
           3 @Table(name = "global_revisions_info")
           4 public class SimpleRevEntity {
           5     @Id
           6     @GeneratedValue
           7     @RevisionNumber
           8     @Column(name = "revision_id")
           9     private int id;
          10     @RevisionTimestamp
          11     @Column(name = "revision_timestamp")
          12     private Date timestamp;
          13     /**
          14      * @return the id
          15      */
          16     public int getId() {
          17         return id;
          18     }
          19     /**
          20      * @param id the id to set
          21      */
          22     public void setId(int id) {
          23         this.id = id;
          24     }
          25     /**
          26      * @return the timestamp
          27      */
          28     public Date getTimestamp() {
          29         return timestamp;
          30     }
          31     /**
          32      * @param timestamp the timestamp to set
          33      */
          34     public void setTimestamp(Date timestamp) {
          35         this.timestamp = timestamp;
          36     }
          37 }       

          SimpleListener 代碼如下:
          1 public class SimpleListener implements RevisionListener {
          2     public void newRevision(Object revisionEntity) {
          3         SimpleRevEntity revEnitty = (SimpleRevEntity) revisionEntity;
          4                 //add your additional info to the SimpleRevEntity here
          5     }
          6 }   

          rev entity生成的數據庫表腳本如下:
          CREATE TABLE `global_revisions_info` (
            `revision_id` 
          int(11NOT NULL AUTO_INCREMENT,
            `revision_timestamp` 
          datetime DEFAULT NULL,
            
          PRIMARY KEY (`revision_id`)
          ) ENGINE
          =InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;


          3. 數據庫版本修改信息查詢
           1   #獲得 AuditReader  
           2   AuditReader reader = AuditReaderFactory.get(session);
           3  
           4   #根據版本號, 實體主鍵,找到修改之前該版本的數據
           5   Person oldPerson = reader.find(Person.class, personId, revision)
           6 
           7 
           8   #得到某條記錄的所有修改的版本號
           9   List<Number> revisions = reader.getRevisions(Person.class, personId);
          10    
          11   #根據修改版本號,得到修改時間
          12   Date date =  reader.getRevisionDate(revision)
          13  
          14   #根據時間,得到修改的版本號
          15   Number revision = reader.getRevisionNumberForDate(date)
          16    
          17   #得到當前最新的版本號. persist參數據,當為true時,當前的revisionEntityClass如果未進行持久操作,則進行持久操作
          18   <T> T getCurrentRevision(Class<T> revisionEntityClass, boolean persist);



          Good Luck!
          Yours Matthew!








          posted on 2010-08-22 23:20 x.matthew 閱讀(9447) 評論(1)  編輯  收藏 所屬分類: Spring|Hibernate|Other framework
          主站蜘蛛池模板: 昆明市| 凤凰县| 山阳县| 辽宁省| 呼图壁县| 武夷山市| 营山县| 信丰县| 凤山县| 科技| 乌兰察布市| 诸暨市| 襄城县| 溧阳市| 丰县| 方正县| 黑山县| 洱源县| 大余县| 玉山县| 墨竹工卡县| 临夏市| 基隆市| 尉犁县| 大关县| 胶南市| 石林| 阿巴嘎旗| 潼南县| 怀宁县| 泸水县| 客服| 奉新县| 平定县| 柳江县| 屯留县| 梓潼县| 连山| 洛南县| 游戏| 玛曲县|