Hibernate 在操作数据库的时候要执行很多操作,这些动作对用户是透明的。这些操作主要是有拦截器和时间组成
hibernate拦截器可以拦截大多数动作,比如事务开始之后(afterTransactionBegin)、事务完成之前(beginTransactionCompletion)、事务完成之后(afterTransactionCompletion)、持久化对象之前(onSave),一个拦截器必须实现org.hibernate.Interceptor借口,hibernate提供了一个实现该借口的类EmptyInterceptor类
下面编写一个hibernate实例来说明hibernate拦截器的作用
首先编写一个保存持久化对象的信息类EntityInfo
public class EntityInfo {
public Object entityBean;
public Serializable id;
public String[] properties;
public Object getEntityBean() {
return entityBean;
}
public void setEntityBean(Object entityBean) {
entityBean = entityBean;
}
public Serializable getId() {
return id;
}
public void setId(Serializable id) {
this.id = id;
}
public String[] getProperties() {
return properties;
}
public void setProperties(String[] properties) {
this.properties = properties;
}
public String toString()
{
String info = "";
if(entityBean !=null){
info = entityBean.getClass().toString()+"\r\nid:"+id+"\r\n";
if(properties != null){
//处理properties中的所有元素
for(String property:properties){
//得到getter方法名
try {
String getter = "get" + property.substring(0, 1).toUpperCase()+property.substring(1);
//使用反射技术和gettter方法名获得Method对象
Method method = entityBean.getClass().getMethod(getter);
//调用gettter方法,并追加生成要返回的信息
info = info + property + ":" +method.invoke(entityBean).toString() +"\r\n";
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return info;
}
}
实现拦截器类,代码如下
public class EntityBeanInterceptor extends EmptyInterceptor {
private ThreadLocal entityBeans = new ThreadLocal();
@Override
public void afterTransactionBegin(Transaction tx){
entityBeans.set(new HashSet<EntityInfo>());
}
@Override
public void afterTransactionCompletion(Transaction tx){
if(tx.wasCommitted()){
Iterator i = ((Collection)entityBeans.get()).iterator();
while (i.hasNext()) {
//在提交事务之后输出试题bean的内容
EntityInfo info = (EntityInfo) i.next();
//调用方法数据EntityBean对象
processEntityBean(info);
}
}
}
private void processEntityBean(EntityInfo info){
System.out.println(info);
}
@Override
public boolean onSave(Object entity,Serializable id, Object[] state,String[] propertyNames,Type[] types){
EntityInfo info = new EntityInfo();
info.entityBean = entity;
info.properties = propertyNames;
info.id =id;
//在持久化对象后,将对象信息保存到当前线程的HashSet<EntityInfo>对象中
((HashSet<EntityInfo>) entityBeans.get()).add(info);
return false;
}
}
注册拦截器类,本例中在构造Session时创建拦截器类
public class HibernateSessionFactory {
/*其他代码省略*/
private static ThreadLocal threadLocal = new ThreadLocal();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
public static Session getSession(Interceptor... interceptor){
Session session = (Session) threadLocal.get();
if(session == null || !session.isOpen()){
//如果session为空重新建立一个Session工厂
if(sessionFactory == null){
rebuildSessionFactory();
}
//如果interceptor参数值中包含拦截器对象,则安装该拦截器
session = (sessionFactory != null)?((interceptor.length == 0)?sessionFactory.openSession():sessionFactory.openSession(interceptor[0])):null;
//如果ThreadLocal对象中没有属于当前线程的session对象,则添加一个Session对象
threadLocal.set(session);
}
}
}
测试拦截器类
public class TestInterceptor {
private void mian() {
// TODO Auto-generated method stub
Session session = HibernateSessionFactory.getSession(new EntityBeanInterceptor());
Transaction tx = session.beginTransaction();
//Customer是一个实体bean
Customer customer = new Customer();
customer.setName("hqw");
session.saveOrUpdate(customer);
tx.commit();
session.close();
}
}
这样在构造session时就注册了拦截器,应为本文在EntityInterceptor类中注册了在事务开始后、事务完成后、持久化后三个方法,所以在相应地方就会调用拦截器中的方法