Hibernate 拦截器实例
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类中注册了在事务开始后、事务完成后、持久化后三个方法,所以在相应地方就会调用拦截器中的方法