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

  • 相关阅读:
    大话字符串逆序
    Class文件结构全面解析(上)
    怎么把CAT客户端的RootMessageId记录到每条日志中?
    阅读JDK源码后,我有了优化它的冲动!
    CAT客户端如何从Apollo中读取配置?
    Sublime Text 3许可证
    通俗易懂地给女朋友讲:线程池的内部原理
    五分钟后,你将学会在SpringBoot项目中如何集成CAT调用链
    分布式监控CAT服务端的本地部署
    如何优雅的设置线程池的大小?
  • 原文地址:https://www.cnblogs.com/haquanwen/p/3812609.html
Copyright © 2020-2023  润新知