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 阅读(9327) 评论(1)  编辑  收藏 所属分类: Spring|Hibernate|Other framework

只有注册用户登录后才能发表评论。


网站导航: