[读书总结]Hibernate的事件框架

原创 2007年09月28日 17:08:00
   通常,载Hibernate执行持久化的过程中,应用程序无法参与其中。因为所有的数据持久化操作,对用户都是透明的,所以用户无法加入自己的动作。 
   通过事件框架,Hibernate允许应用程序能响应特定的内部事件,从而实现某些通用的功能,或者允许对Hibernate功能进行扩展。
   Hibernate的事件框架由以下两部分组成。
      ●拦截器机制:对于特定动作拦截,回调应用中的特定动作。
   ●事件系统:重写Hibernate的事件监听器。
   1.拦截器:
      通过Inteceptor接口,可以从Session中回调应用程序的特定方法,这种回调机制可让应用程序在持久化对象被保存,更新,删除或加载之前,对其进行检查并修改其属性。
      通过Inteceptor接口,可以在数据进入数据库之前,对数据进行最后的检查,如果数据不符合要求,则可以修改,从而避免非法数据进入数据库。当然,通常无须这样做,只有在某些特殊的场合下,才考虑使用拦截器完成检查功能。
      使用拦截器时按如下步骤进行:
         (1)定义实现Interceptor接口的拦截器类。
         (2)通过Session起用拦截器,或者通过Configuration启用全局拦截器。
      下面是一个拦截器的简单示例的代码:
public class MyInterceptor extends EmptyInterceptor {
    public void onDelete(Object entity,Serializable id,Object[] state,
        String[] propertyNames,Type[] types) {
         System.out.println("该方法在删除数据时调用");
   }
}
   拦截器的使用有两种方法:
      ●通过SessionFactory的openSession(Interceptor in)方法打开一个带局部拦截器的Session。
   ●同过Configuration的setInterceptor(Interceptor in)方法设置全局拦截器。
      下面是使用拦截器的示例的部分代码:
public class HibernateUtil {
   public static final SessionFactory sessionFactory;
   static{
      try{
         Configuration configuration = new Configuration().configure();
         sessionFactory = configuration.buildSessionFactory();
      }catch (Throwable ex) {
         System.err.println("初始化sessionFactory失败。" + ex);
         throw new ExceptionInInitializerError(ex);
      }
   }
   public static final ThreadLocal session = new ThreadLocal();
   public static Session currentSession(Interceptor it) throws HibernateException {
      Session s = (Session) session.get();
      if(s == null) {
         s = sessionFactory.openSession(it);
         session.set(s);
      }
      return s;
   }
   public static void closeSession() throws HibernateException {
       Session s = (Session) session.get();
       if (s != null)
         s.close();
       session.set(null);
   }
}
   2.事件系统:
      Hibernate3事件系统是功能更强大的事件框架,该事件系统可以替代拦截器,也可以作为拦截器的补充来使用。
      基本上,Session接口的每个方法都有对应的事件。比如LoadEvent,FlushEvent等。事实上,当Session调用某方法时,Hibernate Session会生成对应的事件,并激活对应的事件监听器。在系统默认监听器实现的处理过程中,完成了对所有的数据持久化的操作,包括插入和修改等操作。如果用户定义了自己的监听器,则意味着用户必须完成对象的持久化操作。
      例如,可以在系统中实现并注册LoadEventListener,该监听器负责处理所有调用Session的load()的方法的请求。
      由于监听器是单态模式对象,即所有的同类型的事件处理共享同一个监听器实例,因此,此监听器不应该保存任何状态,即不应该使用成员变量。
      使用事件系统时按如下步骤进行:
         (1)实现自己的事件监听器类。
         (2)注册自定义事件监听器,代替系统默认的事件监听器。
      实现用户的自定义监听器有如下三个方法:
      ●实现对应的监听器接口:这是不可思议的,实现接口必须实现接口内的所有方法,关键是必须实现Hibernate对应的持久化操作,即数据库访问,这意味着程序员完全取代了Hibernate的底层操作。
   ●继承事件适配器:可以选择地实现需要关注的方法,但依然需要替代Hibernate完成数据库访问。这也不太现实。
   ●继承系统默认的事件监听器:扩展特定的方法。
      实际上,前两种方法很少使用。因为Hibernate的持久化操作也是通过这些监听器实现的,如果用户取代了这些监听器,则应该自己实现持久化操作,这意味着用户放弃了Hibernate的持久化操作,而改为自己完成Hibernate的核心操作。
      通常我们采用第三种方法实现自己的事件监听器。因为Hibernate默认的事件监听器被声明成non-final,从而方便用户继承。
      下面是用户自定义监听器的示例:
//自定义LoadListener,继承默认的DefaultLoadEventListener实现类
public class MyLoadListener extends DefaultLoadEventListener {
    //在LoadEventListener接口仅仅定义了这个方法
    public Object onLoad(LoadEvent event,LoadEventListener.LoadType loadType)
        throws HibernateException {
        Object o = super.onLoad(event,loadType);
        System.out.println("自定义的load事件");
        System.out.println(event.getEntityClassName() + "---------"
             + event.getEntityId());
        return o;
    }
}
      注册用户自定义监听器也有以下两种方法。
         ●编程式:通过使用Configuration对象编程注册。
     ●声明式:在Hibernate的XML格式的配置文件中进行声明,使用Properties格式的配置文件将无法配置自定义监听器。
      通过编程式方式使用自定义监听器时,只需将HibernateUtil中的静态块儿用如下的静态块儿替代即可:
      static{
         try{
            Configuration cfg = new Configuration();
            cfg.getSessionEventListenerConfig().setLoadEventListener(
               new MyLoadListener());
            sessionFactory = cfg.configure().buildSessionFactory();
   
         } catch(Throwable ex) {
            System.err.println("初始化sessionFactory失败。" + ex);
            throw new ExceptionInInitializerError(ex);
         } 
      }
      
      使用声明式方式使用自定义监听器时,可在Hibernate配置文件中的<session-factory>元素中增加:
         <listener type="load" class="MyLoadListener">
子元素即可。
      使用配置文件注册事件监听器虽然方便,但也有不利之处:通过配置文件注册的监视器不能共享实例;如果有多个<listener/>元素中使用了相同的类,则每个引用都将产生一个新拦截器实例;如果需要在多个事件之间共享监听器的实例,则必须使用编程式方式来注册事件监听器。
      虽然监听器类实现了特定监听器的接口,但在注册时还要明确指出注册的事件。因为一个类可能实现多个监听器的接口,所以,在注册时明确指定要监听的事件,可以使得启用或者禁用某个事件的监听配置工作更加简单。 

相关文章推荐

Hibernate读书笔记-----事件机制

Hibernate执行持久化过程中,应用程序无法参与其中。所有的数据持久化操作,对用户都是透明的。           通过事件框架,Hibernate允许应用程能响应特定的内部事件,从而允许实现某...
  • chenssy
  • chenssy
  • 2012年07月13日 08:43
  • 2744

hibernate 拦截器和事件框架

注册监听器: MyPreInsertListener.java: [java] view plaincopy package eventL...

hibernate 拦截器和事件框架

注册监听器: MyPreInsertListener.java: package eventListener; import org.hibernate.event.PreInsertEve...

hibernate 拦截器和事件框架

注册监听器: MyPreInsertListener.Java: [java] view plain copy package event...
  • yztezhl
  • yztezhl
  • 2016年08月02日 18:01
  • 277

javascript高级程序设计读书笔记——事件总结

第13章 事件 1.1 事件冒泡     事件开始的时候从最具体的元素接收,然后逐级向上传播到较为不具体的节点。 1.2 事件捕获     事件捕获与冒泡相反,首先由不具体的节点接收,最后...

java三大框架struts+hibernate+spring学习总结

Struts  1. struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是 ActionServlet的子...

struts2+spring+hibernate三大框架环境搭建小小总结

一、环境搭建 导入各种jar包什么的就不多说了。 二、整个包结构及模式: 1、src文件下,由com.companyname组成一个大的包结构和各项配置文件组成 2、companyname下,分成两部...

Hibernate框架的总结

hibernate 简介: hibernate是一个开源框架,它是对象关联关系映射的框架,它对JDBC做了轻量级的封装,而我们java程序员可以使用面向对象的思想来操纵数据库。 hibernate...

Hibernate框架总结

Hibernate在MVC的设计模式中,充当的是M(Model)模型层(或数据访问层),其实现的功能是将Java对象或是叫PO对象映射到数据库,然后通过操作PO,实现对数据 的增删改查等功能。 Hi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[读书总结]Hibernate的事件框架
举报原因:
原因补充:

(最多只允许输入30个字)