`

12-Hibernate3.6.2 事件机制

阅读更多

         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接口的每个方法都有相对应的事件。比如 LoadEventFlushEvent,等等。当某个方法被调用时,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-distribution-3.6.2 API及jar包

    《Hibernate 3.6.2 API及jar包详解》 Hibernate,作为一个强大的对象关系映射(ORM)框架,是Java开发中的重要工具。本资源集合包含`hibernate-distribution-3.6.2`版本的API中文文档以及相关的jar包,旨在帮助...

    hibernate-distribution-3.6.2.Final-dist

    `hibernate-distribution-3.6.2.Final`包含了完整的Hibernate源代码,便于开发者深入理解其内部机制。其中主要的模块包括: 1. `hibernate-core`: Hibernate的核心组件,包含对象/关系映射、查询、事务处理等功能。 ...

    hibernate-distribution-3.6.2.Final-dist jar包

    12. **延迟加载(Lazy Loading)**:Hibernate支持懒加载机制,即当需要访问关联对象时才进行数据库查询,提高性能。 以上就是`hibernate-distribution-3.6.2.Final-dist` jar包中涉及的主耍知识点。这个包包含了...

    Hibernate Core 3.3.2.GA API (html官方英文版)

    Hibernate允许注册事件监听器,如PreInsertEventListener、PreUpdateEventListener等,可以在特定事件发生时执行自定义逻辑。 综上所述,Hibernate Core 3.3.2.GA API提供了全面且强大的功能,包括对象关系映射、...

    spring4.2+hibernate4.2+struts2.3.29整合所需jar包

    标题中的"spring4.2+hibernate4.2+struts2.3.29整合所需jar包"指的是在Java开发中,将Spring 4.2、Hibernate 4.2和Struts 2.3.29这三大主流框架进行集成时所需的库文件。这些jar包是开发人员构建基于SSH(Spring、...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     9.3 Hibernate的事件处理机制  9.4 批量处理数据  9.4.1 通过Session来进行批量操作  9.4.2 通过StatelessSession来进行批量操作  9.4.3 通过HQL来进行批量操作  9.4.4 直接通过JDBC API来进行批量操作  9.5...

    jeesite lib2包

    Hibernate提供事务管理、缓存机制和强大的查询语言HQL,是Java领域中广泛使用的持久层框架。 2. **org.insightech.er_1.0.0.v20121127-2328.jar**:这是ER图设计工具Insight-ER的一部分,用于设计和管理数据库的...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    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 本章介绍...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     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:Java 对象持久化技术详解(第2版).part3

     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:Java 对象持久化技术详解(第2版).part1.rar

     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:对象持久化技术第二版part3

    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.2lucene 3 6 2 SSH整合1.0版

    Struts2.3.8、Hibernate4.2和Spring3.2是Java开发中的三大主流框架,它们分别负责Web层、持久层和业务层的管理,而Lucene 3.6.2则是一个强大的全文搜索引擎库。这个整合版本称为SSH整合1.0版,旨在提供一个高效、...

    JAVA程序开发技术

    - 阻塞(Blocked):等待某个事件完成才能继续运行; - 死亡(Terminated):线程已执行完毕或被强制终止。 **1.2.3 线程的调度** - **调度机制**:操作系统负责线程的调度。 - **策略**: - 先来先服务(First-...

    JAVA程序开发大全---上半部分

    第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 下载...

    J2EEWEB开发教材

    ### J2EE Web 开发关键...J2EE 技术栈包含了 Java Servlet、JSP、Spring、Hibernate 和 Struts 等核心组件,这些技术共同构成了企业级应用的基础。通过学习这些技术,开发者可以构建出功能强大且可扩展的 Web 应用。

Global site tag (gtag.js) - Google Analytics