Hibernate拦截器回调机制

Interceptor接口提供了从会话(session)回调(callback)应用程序(application)的机制, 这种回调机制可以允许应用程序在持久化对象被保存、更新、删除或是加载之前,检查并(或)修改其 属性。一个可能的用途,就是用来跟踪审核(auditing)信息。例如:下面的这个拦截器,会在一个实现了 Auditable接口的对象被创建时自动地设置createdBy和createdDt属性。

创建AuditInfo.java这个bean封装这些Audit的信息

public class AuditInfo  {
	
	private int createdBy;
	private Date createdDT;

	public int getCreatedBy() {
		return createdBy;
	}

	public void setCreatedBy(int createdBy) {
		this.createdBy = createdBy;
	}

	public Date getCreatedDT() {
		return createdDT;
	}

	public void setCreatedDT(Date createdDT) {
		this.createdDT = createdDT;
	}

}

 

创建Auditable.java.我这里为方便采用的是abstract class,建议使用interface.

Auditable接口是用来让hibernate PO来继承的

public class User extends Auditable {}

 

我这里将AuditInfo和UserTo都放入Auditable,所有继承Auditable的PO都会继承这两个属性

UserTo是用户登录后存放在session中的用户信息,如userid,username之类的.

public abstract class Auditable implements java.io.Serializable {
	private static final long serialVersionUID = 1L;
	
	private AuditInfo auditInfo;
	private UserTo userTo;

	public UserTo getUserTo() {
		return userTo;
	}

	public void setUserTo(UserTo userTo) {
		this.userTo = userTo;
	}

	public AuditInfo getAuditInfo() {
		return auditInfo;
	}

	public void setAuditInfo(AuditInfo auditInfo) {
		this.auditInfo = auditInfo;
	}
}

 

让PO继承Auditable,

public class User extends Auditable {}

同时需要在对应的mapping配置文件中设置映设关系

 

<hibernate-mapping package="report.model.hibernate.po">
	<class name="User" table="c_user">
		<id name="userId" type="int" column="user_id">
			<generator class="identity">
			</generator>
		</id>
		<property name="userName" type="java.lang.String" column="user_name" />
		<property name="password" type="java.lang.String" column="password" />
		<component name="auditInfo"
			class="report.common.hibernate.interceptor.AuditInfo">
			<property name="createdBy" type="int" column="created_by" />
			<property name="createdDT" type="java.sql.Date" column="created_dt" />
		</component>

	</class>
</hibernate-mapping>

 

现在开始写AuditInterceptor

public class AuditInterceptor extends EmptyInterceptor {
	private static final Log log = LogFactory.getLog(UserServiceImpl.class);

	public boolean onSave(Object entity, Serializable id, Object state[],
			String as[], Type atype[]) {
		log.info("AuditInterceptor onSave begin");
		if (entity instanceof Auditable) {
			AuditInfo info = new AuditInfo();
			info.setCreatedBy(((Auditable) entity).getUserTo().getUserId());
			info.setCreatedDT(new Date(System.currentTimeMillis()));
			for(int i=0;i<as.length;i++){
				if("auditInfo".equals(as[i])){
					state[i]=info;
					log.info("insert audit info");
					return true;
				}
			}
			log.info("Created by "+((Auditable) entity).getUserTo().getUserName());			
		}
		return false;
	}
	
    public boolean onLoad(Object entity, Serializable id, Object state[], String as[], Type atype[])
    {
    	log.info("AuditInterceptor onLoad begin");
        return false;
    }

}

 

拦截器可以有两种:Session范围内的,和SessionFactory范围内的。

当使用某个重载的SessionFactory.openSession()使用Interceptor作为参数调用打开一个session的时候,就指定了Session范围内的拦截器。

Session session = sf.openSession( new AuditInterceptor() );

SessionFactory范围内的拦截器要通过Configuration中注册,而这必须在创建SessionFactory之前。在这种情况下,给出的拦截器会被这个SessionFactory所打开的所有session使用了;除非session打开时明确指明了使用的拦截器。SessionFactory范围内的拦截器,必须是线程安全的,因为多个session可能并发使用这个拦截器,要因此小心不要保存与session相关的状态。

new Configuration().setInterceptor( new AuditInterceptor() );

 

在Spring中配置Interceptor:

	<!-- Transaction config start  -->
	<bean id="txManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
		<property name="entityInterceptor" ref="auditInterceptor" />
	</bean>
	<!-- HibernateTemplate Begin-->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<constructor-arg ref="sessionFactory" />
		<property name="entityInterceptor" ref="auditInterceptor" />
	</bean>
	<!-- HibernateTemplate End -->

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值