文档章节

hibernate中拦截器与事件监听器的区别

z_jordon
 z_jordon
发布于 2015/04/22 21:48
字数 617
阅读 121
收藏 0

关于hibrenate中拦截器与事件监听器的介绍和使用的文章可以参看这篇文章:

 Hibernate拦截器(Interceptor)与事件监听器(Listener)

关于在hibernate中使用拦截器实现增删改查日志记录的文章可参看这篇文章:

Hibernate4 拦截器(Interceptor) 实现实体类增删改的日志记录

拦截器与事件监听器的区别在于

  1. 监听器比拦截器提供更加细粒度的控制

    监听器可以提供以下几种级别的事件的监听:

而拦截器只提供以下几种事件的监听:

2. 监听器比拦截器更加底层,拦截器是在对应的监听器中被启动的,这点可以看hibernate的代码,比如在org.hibernate.event.internal.DefaultFlushEntityEventListener中调用了对应的拦截器,代码如下:

protected boolean invokeInterceptor(
			SessionImplementor session,
			Object entity,
			EntityEntry entry,
			final Object[] values,
			EntityPersister persister) {
		return session.getInterceptor().onFlushDirty(
				entity,
				entry.getId(),
				values,
				entry.getLoadedState(),
				persister.getPropertyNames(),
				persister.getPropertyTypes()
		);
	}

3.在监听器中可以取到session,但在拦截器中不行,比如前面那篇用拦截器实现增删改查日志的例子中只能很无奈的调用HibernateUtil.getSessionFactory().openSession()来重新打开一个session了,但在监听器中可以通过AbstractEvent的getSession方法来获取session,如下:

protected boolean handleInterception(FlushEntityEvent event) {
		SessionImplementor session = event.getSession();

4.但拦截器使用起来会比监听器直观,比如同样是想监听同步数据库前实体的状态,用拦截器的onFlushDirty方法可以很直接的取到更新前的状态和更新后的值,如下:

public boolean onFlushDirty(
			Object entity, 
			Serializable id, 
			Object[] currentState, 
			Object[] previousState, 
			String[] propertyNames, 
			Type[] types) {

其中,currentState是更新后的值,previousState是更新前的值。

而如果用监听器的话,需要先通过event中获取到对应的持久化实例,再从实例中获取到对应的属性,如下是在DefaultFlushEntityEventListener类中调用拦截器的过程:

EntityEntry entry = event.getEntityEntry();
		EntityPersister persister = entry.getPersister();
		Object entity = event.getEntity();
final Object[] values = event.getPropertyValues();
		final boolean intercepted = invokeInterceptor( session, entity, entry, values, persister );
protected boolean invokeInterceptor(
			SessionImplementor session,
			Object entity,
			EntityEntry entry,
			final Object[] values,
			EntityPersister persister) {
		return session.getInterceptor().onFlushDirty(
				entity,
				entry.getId(),
				values,
				entry.getLoadedState(),
				persister.getPropertyNames(),
				persister.getPropertyTypes()
		);
	}

所以综上几点,如果不需要非常细粒度的监听hibernate中的事件的话优先使用拦截器,但如果想在监听的同时获取到sessionc对象的又不想重新打开一个session的话请务必使用监听器。

© 著作权归作者所有

共有 人打赏支持
z_jordon
粉丝 35
博文 251
码字总数 78212
作品 0
厦门
技术主管
粗谈Hibernate——从执行顺序来看Hibernate

1.实例化Configuration对象 Hibernate在WEB-INF下查找hibernate.cfg.xml配置文件,根据hibernate.cfg.xml配置文件中配置的信息实例化Configuration对象 。如果使用了事件系统的话,在实例化C...

Robinson_lu
2015/06/18
0
0
Hibernate基础知识汇总

ORM简介 ORM(Object/Relation Mapping),对象关系映射,ORM是一种规范,主要完成面向对象的编程语言到关系数据库的映射。 ORM框架是面向对象程序设计语言与关系数据库发展不同步时的中间解...

白志华
2015/09/17
6
0
Hibernate的拦截器和监听器

最近项目需要,用到了Hibernate的拦截器和监听器,有些小小心得,和大家分享下。 首先说说这两个东西。 拦截器(Intercept):顾名思义,拦截操作,也就是在Hibernate做出动作之前会调用的方...

Zero零_度
2015/09/23
256
0
spring boot(7)监听器、过滤器和拦截器

1 监听器、过滤器和拦截器 1.1 监听器 监听器Listener,它是实现了javax.servlet.XXXListener接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要...

刘胜球
2017/10/29
0
0
过滤器、监听器、拦截器的区别

1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客...

旋转木马-千里马
2016/01/20
86
0

没有更多内容

加载失败,请刷新页面

加载更多

用Golang做了一个命令行贪吃蛇游戏

用Golang做了一个命令行贪吃蛇游戏 项目介绍 项目链接:https://gitee.com/lwow2025/snake-go 最近看了一本做几个小项目的书,突然就想用Golang做一个命令行贪吃蛇,也没啥特殊原因。 软件架...

Mediv
20分钟前
0
0
storm的利用并行度提高处理速度的经验

在storm的流计算框架中,在数据量非常大或者计算逻辑比较复杂的情况下,可能会造成处理速度变慢的情况,最后反而不满足了系统的处理要求,因此这里讨论一下。本文的内容是我在storm的使用过程...

飓风2000
30分钟前
0
0
课程推荐|深入浅出区块链博主:全栈区块链开发者的4堂必修课(线上优惠)

Tiny熊从2017年开始更新“深入浅出区块链”博客,在第一篇文章中,关于如何系统学习区块链技术,他这样描述:“从事区块链开发也有很多方向,如:区块链应用开发人员、区块链架构师、底层核心...

HiBlock
42分钟前
0
0
激活win10 亲测有效

1.首先,我们先查看一下Win10正式专业版系统的激活状态: 点击桌面左下角的“Windows”按钮,从打开的扩展面板中依次点击“设置”-“更新和安全”,并切换到“激活”选项卡,在此就可以查看到...

可达鸭眉头一皱
43分钟前
0
0
SpringWind180926

SpringWind SpringWind项目代码学习笔记 /SpringWind/src/main/webapp/WEB-INF/views/login.html 第15行action="#springUrl('/account/login.html')"【为什么是#springUrl】 第4行<a class=......

颖伙虫
56分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部