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) { // 每同步一次,修改的累加器加1 updates++; 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() );
Configuration cfg = new Configuration().configure().setInterceptor(new MyIterceptor()); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); for (int i = 0; i < 2; i++) { Category c = new Category(); c.setName("c" + i); session.save(c); } tx.commit(); session.close();
insert into Category (name) values (?) Hibernate: insert into Category (name) values (?) 创建的次数: 2, 更新的次数: 0 事务即将结束 事务已经结束
二、事件机制
如果需要响应持久层的某些特殊事件,可以使用Hibernate3的事件框架。该事件系统可以用来替代拦截器,也可以作为拦截器的补充来使用。Session接口的每个方法都有相对应的事件。比如 LoadEvent,FlushEvent,等等。当某个方法被调用时,Hibernate Session会生成一个相对应的事件并激活所有配置好的事件监听器。
系统默认监听器实现的处理过程,完成了所有的数据持久化操作,包括插入、修改等操作。如果用户自己定义了自己的监听器,则意味着用户必须完成对象的持久化操作。
监听器是单例模式对象,即所有同类型的事件处理共享同一个监听器实例,因此监听器不应该保存任何状态,即不应该使用成员变量。
使用事件系统按如下步骤:
1、实现自己的事件监听器
2、注册自定义事件监听器,代替系统默认的事件监听器
实现用户的自定义监听器有如下三种方法:
1、实现对应的监听器接口。实现接口必须实现接口内的所有方法,关键是必须事件Hibernate对应的持久化操作,即数据库访问,这意味着程序员完全取代了Hibernate的底层操作。
2、继承事件适配器。可以选择性地实现需要关注的方法,但依然试图取代Hibernate完成数据库的访问。
3、继承系统默认的事件监听器。扩展特定方法。
下面是自定义监听器实例:
import org.hibernate.HibernateException; import org.hibernate.event.LoadEvent; import org.hibernate.event.LoadEventListener; import org.hibernate.event.def.DefaultLoadEventListener; 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.iflytek.filter.MyLoadListener"); conf.setListener("save", "com.iflytek.filter.MySaveListener"); SessionFactory sfg = conf.buildSessionFactory(); Session session = sfg.openSession(); Transaction tx = session.beginTransaction(); Category category= new Category(); category.setId(1); category.setName("1111"); session.save(category); // 调用save方法,触动save监听器 tx.commit(); session.load(Category.class, 1); // 调用load方法,触动load监听器 session.close(); }
2、声明式。在hibernate.cfg.xml配置文件中进行声明。
注册事件监听器使用<listener.../>元素。该元素可以接受两个参数。
type:指定该事件监听器所监听的事件类型,class:指定事件监听器的实现类
<listener class="com.iflytek.listener.MyLoadListener" type="load"/> <listener class="com.iflytek.listener.MySaveListener" type="save"/>
如果需要为指定事件配置多个事件监听器,则需要使用<event.../>元素。在<event.../>元素里可以使用多个<listener.../>子元素来指定多个事件监听器。
<event type="save"> <listener class="com.iflytek.listener.MySaveListener"/> <listener class="com.iflytek.listener.MyLoadListener"/> </event>
相关推荐
《Hibernate 3.6.2 API及jar包详解》 Hibernate,作为一个强大的对象关系映射(ORM)框架,是Java开发中的重要工具。本资源集合包含`hibernate-distribution-3.6.2`版本的API中文文档以及相关的jar包,旨在帮助...
`hibernate-distribution-3.6.2.Final`包含了完整的Hibernate源代码,便于开发者深入理解其内部机制。其中主要的模块包括: 1. `hibernate-core`: Hibernate的核心组件,包含对象/关系映射、查询、事务处理等功能。 ...
12. **延迟加载(Lazy Loading)**:Hibernate支持懒加载机制,即当需要访问关联对象时才进行数据库查询,提高性能。 以上就是`hibernate-distribution-3.6.2.Final-dist` jar包中涉及的主耍知识点。这个包包含了...
Hibernate允许注册事件监听器,如PreInsertEventListener、PreUpdateEventListener等,可以在特定事件发生时执行自定义逻辑。 综上所述,Hibernate Core 3.3.2.GA API提供了全面且强大的功能,包括对象关系映射、...
标题中的"spring4.2+hibernate4.2+struts2.3.29整合所需jar包"指的是在Java开发中,将Spring 4.2、Hibernate 4.2和Struts 2.3.29这三大主流框架进行集成时所需的库文件。这些jar包是开发人员构建基于SSH(Spring、...
9.3 Hibernate的事件处理机制 9.4 批量处理数据 9.4.1 通过Session来进行批量操作 9.4.2 通过StatelessSession来进行批量操作 9.4.3 通过HQL来进行批量操作 9.4.4 直接通过JDBC API来进行批量操作 9.5...
Hibernate提供事务管理、缓存机制和强大的查询语言HQL,是Java领域中广泛使用的持久层框架。 2. **org.insightech.er_1.0.0.v20121127-2328.jar**:这是ER图设计工具Insight-ER的一部分,用于设计和管理数据库的...
3.6.2 创建helloapp应用的目录结构 72 3.6.3 把helloapp应用作为独立应用程序运行 73 3.6.4 把helloapp应用作为Java Web应用运行 77 3.7 小结 78 3.8 思考题 80 第4章 hbm2java和hbm2ddl工具 83 本章介绍...
9.3 Hibernate的事件处理机制 9.4 批量处理数据 9.4.1 通过Session来进行批量操作 9.4.2 通过StatelessSession来进行批量操作 9.4.3 通过HQL来进行批量操作 9.4.4 直接通过JDBC API来进行批量操作 9.5...
9.3 Hibernate的事件处理机制 9.4 批量处理数据 9.4.1 通过Session来进行批量操作 9.4.2 通过StatelessSession来进行批量操作 9.4.3 通过HQL来进行批量操作 9.4.4 直接通过JDBC API来进行批量操作 9.5...
9.3 Hibernate的事件处理机制 9.4 批量处理数据 9.4.1 通过Session来进行批量操作 9.4.2 通过StatelessSession来进行批量操作 9.4.3 通过HQL来进行批量操作 9.4.4 直接通过JDBC API来进行批量操作 9.5...
3.6.2 创建helloapp应用的目录结构 72 3.6.3 把helloapp应用作为独立应用程序运行 73 3.6.4 把helloapp应用作为Java Web应用运行 77 3.7 小结 78 3.8 思考题 80 第4章 hbm2java和hbm2ddl工具 83 本章介绍...
Struts2.3.8、Hibernate4.2和Spring3.2是Java开发中的三大主流框架,它们分别负责Web层、持久层和业务层的管理,而Lucene 3.6.2则是一个强大的全文搜索引擎库。这个整合版本称为SSH整合1.0版,旨在提供一个高效、...
- 阻塞(Blocked):等待某个事件完成才能继续运行; - 死亡(Terminated):线程已执行完毕或被强制终止。 **1.2.3 线程的调度** - **调度机制**:操作系统负责线程的调度。 - **策略**: - 先来先服务(First-...
第12章 Struts 2.0的开发及应用 214 12.1 Struts 2.0框架概述 214 12.1.1 Struts 2.0框架工作流程 214 12.1.2 Struts 2.0与Struts 1.x框架的区别 215 12.2 MyEclipse创建基于Struts 2.0框架的项目 215 12.2.1 下载...
### J2EE Web 开发关键...J2EE 技术栈包含了 Java Servlet、JSP、Spring、Hibernate 和 Struts 等核心组件,这些技术共同构成了企业级应用的基础。通过学习这些技术,开发者可以构建出功能强大且可扩展的 Web 应用。