最近项目须要,用到了Hibernate的拦截器和监听器,有些小当心得,和你们分享下。
首先说说这两个东西。
拦截器(Intercept):顾名思义,拦截操做,也就是在Hibernate作出动做以前会调用的方法。若是你有须要在Hibernate操做数据库以前想要作的操做,就须要用到这个东西了。
监听器(Listener):监听,就是监视Hibernate的一举一动,若是咱们要获取Hibernate各类操做PO的前先后后的信息,那就要用到他了。
这里有的朋友可能就有疑问了,从上面的描述来看,这个监听器彷佛可以实现拦截器的功能,由于他也能获取Hibernate操做数据库前的情况。
其实否则,在此我只举出两个很典型的例子,你们就会明白他们俩是不能被互相取代的。
一、监听器只会默默的获取信息,不会阻断Hibernate的工做,而用拦截器时,咱们能够根据咱们的需求,去终止某个Hibernate的持久化动做。
二、若是我有这样一个需求,在PO保存时,我想按个人需求改变某个属性的值后,再保存入库。分析下知道,这个操做要在Hibernate执行 Save以前来作,那么看似拦截器和监听器都能实现,但实践一下就会知道,若是咱们用监听器来作(好比此时用 PreInsertEventListener),当咱们在此改变某属性值后,会发现,保存入库的仍然是原来的值,监听器的Pre******是不容许我 们这样作的。此时就须要用到拦截器,实现其OnSave方法,在此进行处理。
说完了这些,就简单说下他们的用法及配置方法。
1、
首先说监听器,咱们以PostUpdateEventListener讲解
新建一个咱们本身的监听器类,实现PostUpdateEventListener接口便可
spring
public class MyListener extends DefaultLoadEventListener session
implements PostUpdateEventListener { app
public void onPostUpdate(PostUpdateEvent event) { ide
System.out.println(event.getEntity().getClass().getName()+":更新完毕"); post
for (int i = 0; i < event.getState().length; i++) { spa
// 更新前的值 hibernate
Object oldValue = event.getOldState()[i]; orm
// 更新后的新值 对象
Object newValue = event.getState()[i];
//更新的属性名
String propertyName = event.getPersister().getPropertyNames()[i];
}
}
}
若是要实现其余监听器,只需实现其余的监听器接口便可,具体有哪些监听器,你们能够查看Hibernate包下的org.hibernate.event,里面能看到全部的监听器。
以后要加载监听器,我这里只讲解用过spring注入sessionFactory,用property配置的方法,由于另外的两种配置方法在网上很容易搜索到,这里就不重复。
先将咱们的监听器定义到spring中
<bean id="myListener" class="com.app.common.util.hibernateSupport.MyListener">
在sessionFactory的bean标签中加入以下内容:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
...
<property name="eventListeners">
<map>
<entry key="post-update">
<ref bean="myListener" />
</entry>
</map>
</property>
...
</bean>
这样咱们的监听器就能够工做了,当Hibernate执行update操做时,就会输出咱们的信息了。
2、
再来讲说拦截器
拦截器的实现要比监听器简单得多。
咱们只要新建一个本身的拦截器类,继承自org.hibernate.EmptyInterceptor类,重写原来的方法,以后在spring中配置便可。
简单例子:
public class MyIntercept extends EmptyInterceptor {
@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {
//entity就是当前的实体对象
//若是当前操做的TbUser,则作处理
if(entity instanceof TbUser){
TbUser user=(TbUser)entity;
user.setUserPassword("123");
if(user.getUserId()==null){
//返回true则拦截本次操做
return true;
}
}
return super.onSave(entity, id, state, propertyNames, types);
}
}
配置文件:
<bean id="myIntercept"
class="com.app.common.util.hibernateSupport.MyIntercept">
.......
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
...
<property name="entityInterceptor">
<ref bean="myIntercept"/>
</property>
...
</bean>
以上内容基于Hibernate3,2.xx相似附件附上org.hibernate.event.EventListeners的源码文件,里面有配置配置文件时不一样拦截器对应的key值,在文件的最下方。