Hibernate envers开发指南

Hibernate envers开发指南
测试版本:
 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 ( 11 NOT   NULL ,
3    `rev`  int ( 11 NOT   NULL ,
4    `revtype`  tinyint ( 4 DEFAULT   NULL ,
5    `age`  int ( 11 DEFAULT   NULL ,
6    `name`  varchar ( 100 DEFAULT   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 ( 11 NOT   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!








你可能感兴趣的:(Hibernate envers开发指南)