`
edisonlv2010
  • 浏览: 43524 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

利用Hibernate 3 Interceptor生成审计日志

 
阅读更多
在实际应用中,有可能需要审计对数据库中重要数据的更新历史。如:每当发生向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,这个类中的所有方法实际上什么也不做,用户自定义的拦截器类也可以扩展此类。

package com.jintoufs.common.hibernate;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

import org.cosmos.core.orm.entity.AuditableEntity;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AuditInterceptor extends EmptyInterceptor {

	private static final long serialVersionUID = -7481545873785342485L;
	private static Logger logger = LoggerFactory.getLogger(AuditInterceptor.class);

	/**
	 *  拦截hibernate save方法(即保存对象之前回调此方法),添加审计信息
	 *  entity - POJO Instance
	 *  id - POJO OID
	 *  state - POJO Instance中每一个属性的值所组成的集合(OID属性除外)     
	 *  propertyNames - POJO Instance中每一个属性的属性名组成的集合(OID属性除外)    
	 *  types - POJO Instance中每一个属性所属类型所对应的Hibernate类型组成的集合(OID属性除外)
	 */
	@Override
	public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {

		String operUserStr = getCurrentUser();

		if (entity instanceof AuditableEntity) {
			for (int index = 0; index < propertyNames.length; index++) {
				if ("createTime".equals(propertyNames[index])) {
					state[index] = new Timestamp(new Date().getTime());
				}
				if ("createBy".equals(propertyNames[index])) {
					state[index] = getCurrentUser();
				}
			}
			logger.info("{}对象(ID:{}) 被 {} 在 {} 创建", new Object[] { entity.toString(), id, operUserStr, new Date() });
			return true;
		}
		return false;
	}

	/**
	 *  拦截hibernate flush方法(即检查到脏对象时回调此方法),添加审计信息
	 *  entity - POJO Instance
	 *  id - POJO OID
	 *  state - POJO Instance中每一个属性的值所组成的集合(OID属性除外)     
	 *  propertyNames - POJO Instance中每一个属性的属性名组成的集合(OID属性除外)    
	 *  types - POJO Instance中每一个属性所属类型所对应的Hibernate类型组成的集合(OID属性除外)
	 */
	public boolean onFlushDirty(Object entity, Serializable id, Object[] state, Object[] previousState,
			String[] propertyNames, Type[] types) {

		String operUserStr = getCurrentUser();

		if (entity instanceof AuditableEntity) {
			for (int index = 0; index < propertyNames.length; index++) {
				if ("lastModifyTime".equals(propertyNames[index])) {
					state[index] = new Timestamp(new Date().getTime());
				}
				if ("lastModifyBy".equals(propertyNames[index])) {
					state[index] = getCurrentUser();
				}
			}
			logger.info("{}对象(ID:{}) 被 {} 在 {} 修改", new Object[] { entity.toString(), id, operUserStr, new Date() });
			return true;
		}
		return false;
	}

	/**
	 * @description 得到当前的操作用户
	 * @return 
	 */
	private String getCurrentUser() {
		String loginName = "test_user";
		//String loginName = SpringSecurityUtils.getCurrentUserName();
		return loginName;
	}
}



applicationContext.xml
<!-- sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
......
<property name="entityInterceptor" ref="auditInterceptor"></property>
......
</bean>

<!-- hibernate审计拦截器 -->
<bean id="auditInterceptor" class="com.jintoufs.common.hibernate.AuditInterceptor" />


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

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


分享到:
评论
1 楼 shnsvyu 2019-05-04  
  

相关推荐

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    Hibernate Recipes

    - **拦截器**: 通过实现`Interceptor`接口来拦截实体的持久化操作,可用于日志记录、审计等场景。 - **事件监听器**: 注册监听器以响应Hibernate的各种事件,如实体加载、更新等。 #### 五、总结 《Hibernate ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    struts2+spring+hibernate网上书店系统

    - 审计日志:记录用户的操作,便于问题追踪和安全审计。 系统开发中,开发人员会使用Maven或Gradle等构建工具来管理和依赖,使用Git进行版本控制,确保团队协作的顺利进行。测试方面,可能会使用JUnit进行单元测试...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     9.2 利用拦截器(Interceptor)生成审计日志  9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作 ...

    基于struts和hibernate的环境保护网管理系统

    4. **日志记录**:系统应记录所有关键操作的日志,以便跟踪和审计,这可以通过集成Apache Log4j等日志框架来实现。 **开发过程**: 开发这样的系统,首先需要进行需求分析,明确系统功能和性能要求。然后进行设计...

    dms电信资费系统

    系统的核心功能是通过日志数据采集,解析和匹配,以生成详细的用户使用报告,进而实现对服务器使用情况的精确计费。下面我们将详细探讨这个系统涉及的技术栈以及其在实际操作中的应用。 首先,Java作为开发语言,是...

    ssh 薪酬管理系统 完整 全面

    3. 薪酬发放记录:记录每次薪酬发放的详情,便于审计和查询。 4. 报表分析:生成各种薪酬相关的报表,如部门薪资总额、员工薪资对比等,为管理层提供决策依据。 5. 权限控制:通过Spring的AOP和安全模块,实现不同...

Global site tag (gtag.js) - Google Analytics