Hibernate执行持久化过程中,应用程序无法参与其中。所有的数据持久化操作,对用户都是透明的。

通过事件框架,Hibernate允许应用程能响应特定的内部事件,从而允许实现某些通用的功能或者对Hibernate功能进行扩展。

Hibernate的事件机制框架由两个部分组成:

1、拦截器机制:对于特定动作拦截,回调应用中的特定动作

2、事件系统:重写Hibernate的事件监听器。

一、拦截器

Interceptor接口提供了从会话回调应用程序的机制,这种回调机制可以允许应用程序在持久化对象被保存、更新、删除或是加载之前,检查并(或)修改其属性。

          通过Interceptor接口,可以在数据进入数据库之前,对数据进行最后的检查,如果数据不符合要求,可以修改数据,从而避免非法数据进入数据库。

使用拦截器按如下两个步骤进行:

1、定义实现Interceptor接口的拦截器

2、通过Session启用拦截器,或者通过Configuration启用全局拦截器

程序可以通过实现Interceptor接口来创建拦截器,也可以通过继承EmptyInterceptor来实现拦截器。

public class MyIterceptor extends EmptyInterceptor {// 记录修改次数private int updates;// 记录创建次数private int creates;// 当删除实体时,onDelete方法将被调用public void onDelete(Object entity, Serializable id, Object[] state,String[] propertyNames, Type[] types) {// do nothing}// 当把持久化实体的状态同步到数据库时,onFlushDirty方法被调用public boolean onFlushDirty(Object entity, Serializable id,Object[] currentState, Object[] previousState,String[] propertyNames, Type[] types) {// 每同步一次,修改的累加器加1updates++;for (int i = 0; i < propertyNames.length; i++) {if ("lastUpdateTimestamp".equals(propertyNames[i])) {currentState[i] = new Date();return true;}}return false;}// 当加载持久化实体时,onLoad方法被调用public boolean onLoad(Object entity, Serializable id, Object[] state,String[] propertyNames, Type[] types) {for (int i = 0; i < propertyNames.length; i++) {if ("name".equals(propertyNames[i])) {// 输出被装载实体的name属性值System.out.println(state[i]);return true;}}return false;}// 保存持久化实例时候,调用该方法public boolean onSave(Object entity, Serializable id, Object[] state,String[] propertyNames, Type[] types) {creates++;for (int i = 0; i < propertyNames.length; i++) {if ("createTimestamp".equals(propertyNames[i])) {state[i] = new Date();return true;}}return false;}// 持久化所做修改同步完成后,调用postFlush方法public void postFlush(Iterator entities) {System.out.println("创建的次数: " + creates + ", 更新的次数: " + updates);}// 在同步持久化所做修改之前,调用preFlush方法public void preFlush(Iterator entities) {}// 事务提交之前触发该方法public void beforeTransactionCompletion(Transaction tx) {System.out.println("事务即将结束");}// 事务提交之后触发该方法public void afterTransactionCompletion(Transaction tx) {System.out.println("事务已经结束");}
}

上面拦截器没有进行实际的操作,只是打印了一些标识代码。

拦截器可以有两种:Session范围内的,和SessionFactory范围内的。

当使用某个重载的SessionFactory.openSession()使用Interceptor作为参数调用打开一个session的时候,就指定了Session范围内的拦截器。

Session session = sf.openSession( new MyInterceptor() );

SessionFactory范围内的拦截器要通过Configuration中注册,而这必须在创建SessionFactory之前。在这种情况下,给出的拦截器会被这个SessionFactory所打开的所有session使用了

new Configuration().setInterceptor( new MyInterceptor() );

示例:

 public void newsTest(){Configuration cfg = new Configuration().configure().setInterceptor(new MyIterceptor());SessionFactory sf = cfg.buildSessionFactory();Session  session = sf.openSession();Transaction tx = session.beginTransaction();//创建一个News对象News news = new News();news.setTitle("搬校区了..");news.setContent("明天我们就要搬校区了,真期待啊....");session.save(news);News news2 = (News) session.load(News.class, 1);news2.setTitle("明天就要搬校区了..");tx.commit();session.close();}

程序运行结果如下:

二、事件机制

如果需要响应持久层的某些特殊事件,可以使用Hibernate3的事件框架。该事件系统可以用来替代拦截器,也可以作为拦截器的补充来使用。

Session接口的每个方法都有相对应的事件。比如 LoadEvent,FlushEvent,等等。当某个方法被调用时,Hibernate Session会生成一个相对应的事件并激活所有配置好的事件监听器。

系统默认监听器实现的处理过程,完成了所有的数据持久化操作,包括插入、修改等操作。如果用户自己定义了自己的监听器,则意味着用户必须完成对象的持久化操作。

监听器是单例模式对象,即所有同类型的事件处理共享同一个监听器实例,因此监听器不应该保存任何状态,即不应该使用成员变量。

使用事件系统按如下步骤:

1、实现自己的事件监听器

2、注册自定义事件监听器,代替系统默认的事件监听器

实现用户的自定义监听器有如下三种方法:

1、实现对应的监听器接口。实现接口必须实现接口内的所有方法,关键是必须事件Hibernate对应的持久化操作,即数据库访问,这意味着程序员完全取代了Hibernate的底层操作。

2、继承事件适配器。可以选择性地实现需要关注的方法,但依然试图取代Hibernate完成数据库的访问。

3、继承系统默认的事件监听器。扩展特定方法。

下面是自定义监听器实例:

public class MyLoadListener extends DefaultLoadEventListener {//在LoadEventListener接口仅仅定义了这个方法public void onLoad(LoadEvent event,LoadEventListener.LoadType loadType) throws HibernateException{System.out.println("自定义的load事件");System.out.println(event.getEntityClassName()+"------"+event.getEntityId());super.onLoad(event, loadType);}
}
public class MySaveListener extends DefaultSaveEventListener{protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event){System.out.println("自定义的save事件");System.out.println(event.getObject());return super.performSaveOrUpdate(event);}
}
          

注意:扩展用户自定义监听器时,别忘了在方法中调用父类的对应的方法,否则Hibernate3默认的持久化行为都会失效。

注册用户自定义监听器有两种方法:

1、编程式。通过使用Configuration对象来编程实现注册。

  public void newsListenerTest(){Configuration conf = new Configuration().configure();//为load事件设置监听器conf.setListener("load", "com.hibernate.filter.MyLoadListener");conf.setListener("save", "com.hibernate.filter.MySaveListener");SessionFactory  sfg = conf.buildSessionFactory();Session session = sfg.openSession();Transaction tx = session.beginTransaction();News news = new News();news.setContent("2222");news.setTitle("1111");session.save(news);           //调用save方法,触动save监听器tx.commit();session.load(News.class, 1);   //调用load方法,触动load监听器session.close();}

2、声明式。在hibernate.cfg.xml配置文件中进行声明。

注册事件监听器使用<listener.../>元素。该元素可以接受两个参数。type:指定该事件监听器所监听的事件类型,class:指定事件监听器的实现类

    <listener class="com.hibernate.listener.MyLoadListener" type="load"/><listener class="com.hibernate.listener.MySaveListener" type="save"/>

如果需要为指定事件配置多个事件监听器,则需要使用<event.../>元素。在<event.../>元素里可以使用多个<listener.../>子元素来指定多个事件监听器。

      <event type="save"><listener class="com.hibernate.listener.MySaveListener"/><listener class="com.hibernate.listener.MyLoadListener"/></event>

转载于:https://www.cnblogs.com/oversea201405/archive/2012/07/13/3752231.html

Hibernate读书笔记-----事件机制相关推荐

  1. Hibernate读书笔记

    伟大的信息管理与信息系统专业,万恶的信息管理与信息系统专业.说这句话我是有根据的:因为这个专业雄心勃勃的想把自己的子弟培养成全面发展的人才但是结果则不然.两方面的原因:一部分在学生,但是一部分在这个专 ...

  2. Hibernate读书笔记---继承映射

    对于面向对象的程序设计语言,继承.多态是两个最基本的概念.Hibernate的继承映射可以理解两个持久化类之间的继承关系. Hibernate支持几种继承映射策略,不管哪种继承映射策略,Hiberna ...

  3. .net框架读书笔记---类型成员及其访问限定(一)

    接上一篇.net框架读书笔记---通用对象操作(三),开始学习类型以及每个类型的所有实例都具有的一组通用操作. 一.类型成员 一个类型可以定义零个或多个以下成员 常数,常数是一个表示恒定不变的数值的符 ...

  4. 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系

    本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...

  5. WPF,Silverlight与XAML读书笔记第八 - WPF新概念之三路由事件

    说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘>的编排,对内容进行了总结并加入一些个人理解. 路由事件是专门设计用于在元素树中使用的事件. ...

  6. 读书笔记:理论生态学原理及应用(一)——合作的机制

    此篇读书笔记对应于<Theoretical Ecology Principles and Applications>第三版第二章--How populations cohere: five ...

  7. Hibernate的事件机制

    4.8 事 件 机 制 通常,Hibernate执行持久化过程中,应用程序无法参与其中.所有的数据持久化操作,对用户都是透明的,用户无法插入自己的动作. 通过事件框架,Hibernate允许应用程序能 ...

  8. 《深入浅出DPDK》读书笔记(五):同步互斥机制

    本文内容为读书笔记,摘自<深入浅出DPDK> 56.原子操作 原子(atom)本意是"不能被进一步分割的最小粒子",而原子操作(atomic operation)意为& ...

  9. 关于数据治理的读书笔记 - 什么是组织机制?

    读书笔记的历史文章, <关于数据治理的读书笔记 - 什么是数据战略?> <关于数据治理的读书笔记 - 企业数据治理的"道.法.术.器"> <关于数据治 ...

  10. PowerPC MMU机制读书笔记

    PowerPC mmu编程模型读书笔记 1概览 PowerPC中的地址分为三类:有效地址EA,是在代码和指令里面使用的:虚拟地址VA,可以看成是中间的转换地址:物理地址PA,实际的真正的内存中的地址. ...

最新文章

  1. Python基础知识学习_Day5
  2. python保留字的基本含义-python 33个保留字是什么意思
  3. 如何设计一个优秀的向导式界面(Wizard)
  4. unity中怎么在InspectorI面板加LOGO
  5. SQL学习--Select(一)TOP、派生表、连接、谓词
  6. android 数据文件存储,实例详解Android文件存储数据方式
  7. js点击事件onclick_关于JavaScript的事件绑定问题
  8. 数据风云、十年变迁(DTCC会议总结)
  9. 异步bus交互(一)— 两级DFF同步器
  10. python sample函数_Python pandas.DataFrame.sample函数方法的使用
  11. 自动备份Linux上的博客数据到坚果云
  12. 使用c语言解析gprmc数据
  13. 科学计算法(机器学习)----决策树定义以相关概念
  14. python怎么表示不等于_Python关系运算符中表示“不等于”的是哪个?________
  15. 有这18个正则表达式,效率嘎嘎上升
  16. 删除所有用户数据!永久关闭
  17. 关于elemen-ui Carousel走马灯图片不显示的问题
  18. HTML5画布Canvas线段、矩形、弧形及贝塞尔曲线等简单图形绘制
  19. Failed at the chromedriver@2.40.0 install script.
  20. buuctf 九连环 解析

热门文章

  1. php pmt,关于光电倍增管(PMT)模块的选型与使用
  2. [codeblocks下实现多个源文件2.0]类声明和成员函数定义的分离实战操作实现
  3. 用Python 开发您的第一个 XGBoost 模型(收藏)
  4. windows php7怎么配置,PHP7在windows7中的环境配置详解
  5. linux安装qq权限不够,[操作系统]Linuxqq安装及其所引发的问题{权限位是 777 (必须 =0755 且 =0755)}...
  6. Docker Kubernetes k8s 从入门到精通
  7. React Native之原理浅析, iOS原理分析与实践解析、Android原理分析与实践解析
  8. java积分签到功能_对于签到功能的一点理解
  9. 395.至少有K个重复字符的最长子串
  10. 邻接矩阵(图的存储)