利用Hibernate 3 Interceptor生成审计日志

本文介绍如何使用Hibernate拦截器实现数据库操作的审计日志记录。通过自定义AuditInterceptor类,可以在保存或更新实体时自动添加创建时间和修改时间等审计信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际应用中,有可能需要审计对数据库中重要数据的更新历史。如:每当发生向T_USER表中插入或更新记录的事件时,就向审计日志表插入一条记录。 

对于此种业务场景,可以采用数据库的触发器来生成审计日志,这种方法较为简便,并且有很好的性能,但是不支持跨数据库平台,缺乏灵活性。因此我们可以采用Hibernate 3以后提供的拦截器来实现相应的功能。当Session执行save()、update()、saveOrUpdate()、delete()以及flush()方法时,就会调用拦截器的相关方法,然后在这些方法中实现审计日志的业务逻辑。 

用户定义的拦截器必须实现org.hibernate.Interceptor接口,在这个接口中主要定义了以下方法。 

onDelete():当Session删除一个对象之前调用此方法。 
onFlushDirty():当Session的flush()方法检查到脏对象时调用此方法。 
onSave():当Session保存一个对象之前调用本方法,如果在这个方法中修改了持久化对象的数据,就返回true,否则返回null。 
postFlush():当Session的flush()方法执行完所有SQL语句后调用此方法。 

在org.hibernate包中还提供了Interceptor接口的一个实现类EmptyInterceptor,这个类中的所有方法实际上什么也不做,用户自定义的拦截器类也可以扩展此类。 

Java代码  收藏代码
  1. package com.jintoufs.common.hibernate;  
  2.   
  3. import java.io.Serializable;  
  4. import java.sql.Timestamp;  
  5. import java.util.Date;  
  6.   
  7. import org.cosmos.core.orm.entity.AuditableEntity;  
  8. import org.hibernate.EmptyInterceptor;  
  9. import org.hibernate.type.Type;  
  10. import org.slf4j.Logger;  
  11. import org.slf4j.LoggerFactory;  
  12.   
  13. public class AuditInterceptor extends EmptyInterceptor {  
  14.   
  15.     private static final long serialVersionUID = -7481545873785342485L;  
  16.     private static Logger logger = LoggerFactory.getLogger(AuditInterceptor.class);  
  17.   
  18.     /** 
  19.      *  拦截hibernate save方法(即保存对象之前回调此方法),添加审计信息 
  20.      *  entity - POJO Instance 
  21.      *  id - POJO OID 
  22.      *  state - POJO Instance中每一个属性的值所组成的集合(OID属性除外)      
  23.      *  propertyNames - POJO Instance中每一个属性的属性名组成的集合(OID属性除外)     
  24.      *  types - POJO Instance中每一个属性所属类型所对应的Hibernate类型组成的集合(OID属性除外) 
  25.      */  
  26.     @Override  
  27.     public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {  
  28.   
  29.         String operUserStr = getCurrentUser();  
  30.   
  31.         if (entity instanceof AuditableEntity) {  
  32.             for (int index = 0; index < propertyNames.length; index++) {  
  33.                 if ("createTime".equals(propertyNames[index])) {  
  34.                     state[index] = new Timestamp(new Date().getTime());  
  35.                 }  
  36.                 if ("createBy".equals(propertyNames[index])) {  
  37.                     state[index] = getCurrentUser();  
  38.                 }  
  39.             }  
  40.             logger.info("{}对象(ID:{}) 被 {} 在 {} 创建"new Object[] { entity.toString(), id, operUserStr, new Date() });  
  41.             return true;  
  42.         }  
  43.         return false;  
  44.     }  
  45.   
  46.     /** 
  47.      *  拦截hibernate flush方法(即检查到脏对象时回调此方法),添加审计信息 
  48.      *  entity - POJO Instance 
  49.      *  id - POJO OID 
  50.      *  state - POJO Instance中每一个属性的值所组成的集合(OID属性除外)      
  51.      *  propertyNames - POJO Instance中每一个属性的属性名组成的集合(OID属性除外)     
  52.      *  types - POJO Instance中每一个属性所属类型所对应的Hibernate类型组成的集合(OID属性除外) 
  53.      */  
  54.     public boolean onFlushDirty(Object entity, Serializable id, Object[] state, Object[] previousState,  
  55.             String[] propertyNames, Type[] types) {  
  56.   
  57.         String operUserStr = getCurrentUser();  
  58.   
  59.         if (entity instanceof AuditableEntity) {  
  60.             for (int index = 0; index < propertyNames.length; index++) {  
  61.                 if ("lastModifyTime".equals(propertyNames[index])) {  
  62.                     state[index] = new Timestamp(new Date().getTime());  
  63.                 }  
  64.                 if ("lastModifyBy".equals(propertyNames[index])) {  
  65.                     state[index] = getCurrentUser();  
  66.                 }  
  67.             }  
  68.             logger.info("{}对象(ID:{}) 被 {} 在 {} 修改"new Object[] { entity.toString(), id, operUserStr, new Date() });  
  69.             return true;  
  70.         }  
  71.         return false;  
  72.     }  
  73.   
  74.     /** 
  75.      * @description 得到当前的操作用户 
  76.      * @return  
  77.      */  
  78.     private String getCurrentUser() {  
  79.         String loginName = "test_user";  
  80.         //String loginName = SpringSecurityUtils.getCurrentUserName();  
  81.         return loginName;  
  82.     }  
  83. }  


applicationContext.xml 
Java代码  收藏代码
  1. <!-- sessionFactory -->  
  2. <bean id="sessionFactory"  
  3. class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">  
  4. <property name="dataSource" ref="dataSource" />  
  5. ......  
  6. <property name="entityInterceptor" ref="auditInterceptor"></property>  
  7. ......  
  8. </bean>  
  9.   
  10. <!-- hibernate审计拦截器 -->  
  11. <bean id="auditInterceptor" class="com.jintoufs.common.hibernate.AuditInterceptor" />  


以上为Spring 3和Hibernate 4整合时的配置方式 

将审计拦截器作为sessionFactory的属性进行配置,即表示此拦截器可以被所有Session实例共享。等同的代码表示方式为:Configuration.setInterceptor(Interceptor inter)。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值