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

posted on 2014-01-03 15:53  hawen  阅读(523)  评论(0编辑  收藏  举报

导航