博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate中拦截器与事件监听器的区别
阅读量:6155 次
发布时间:2019-06-21

本文共 2058 字,大约阅读时间需要 6 分钟。

hot3.png

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

 

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

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

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

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

    212730_dIOW_914897.png

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

213013_kRHy_914897.png

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的话请务必使用监听器。

转载于:https://my.oschina.net/u/914897/blog/405243

你可能感兴趣的文章
内存或磁盘空间不足,Microsoft Office Excel 无法再次打开或保存任何文档。 [问题点数:20分,结帖人wenyang2004]...
查看>>
委托到Lambda的进化: ()=> {} 这个lambda表达式就是一个无参数的委托及具体方法的组合体。...
查看>>
apache 伪静态 .htaccess
查看>>
unity3d 截屏
查看>>
ASP.NET MVC学习之控制器篇
查看>>
MongoDB ServerStatus返回信息
查看>>
分析jQuery源码时记录的一点感悟
查看>>
Sql日期时间格式转换
查看>>
20个最强的基于浏览器的在线代码编辑器 - OPEN资讯
查看>>
Tesseract——OCR图像识别 入门篇
查看>>
《Java程序性能优化》之设计优化
查看>>
Android源代码下载方法具体解释
查看>>
虚拟机 搭建LVS + DR + keepalived 高可用负载均衡
查看>>
maven 发布到仓库
查看>>
Android实现简单短信发送器
查看>>
Linux命令执行顺序— ||和&&和; 比较
查看>>
第30周一
查看>>
一、Bitmap的recycle问题
查看>>
DHCP Option 60 的理解
查看>>
android中的textview显示汉字不能自动换行的一个解决办法
查看>>