`
betafox
  • 浏览: 149632 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hibernate的事件和拦截器体系

阅读更多

 

持久层框架底层的拦截器机制是对诸如Spring等业务管理容器拦截机制的有益补充,使得我们可以在更低层次、更广的对象范围上进行AOP操作(Spring虽然将Hibernate纳入到其容器管理的范围内,但是并没有途径实现对其实体对象的管理)。这样就允许实现某些通用的功能,以及允许对Hibernate功能进行扩展。

  1. 拦截器(Interceptors)

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

你可以直接实现Interceptor接口,也可以(最好)继承自EmptyInterceptor

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

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

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

l         SessionFactory范围内的拦截器要通过Configuration中注册,而这必须在创建SessionFactory之前。在这种情况下,给出的拦截器会被这个SessionFactory所打开的所有session使用了,除非session打开时明确指明了使用的拦截器。SessionFactory范围内的拦截器,必须是线程安全的,因为多个session可能并发使用这个拦截器,要因此小心不要保存与session相关的状态

new Configuration().setInterceptor( new AuditInterceptor() );

spring配合使用时需要配置sessionFactory对象的entityInterceptor属性:

  1 <property name="entityInterceptor">

  2        <bean class="**.AuditTrailInterceptor"/>

  3        <bean class="**.AuditTrailInterceptor2"/>

  4  </property>

 

例如:

A、下面的这个拦截器,会在一个实现了 Auditable接口的对象被创建时自动地设置createTimestamp属性,并在实现了 Auditable接口的对象被更新时,同步更新lastUpdateTimestamp属性。

1 public class AuditInterceptor extends EmptyInterceptor {

  2

  3     private int updates;

  4     private int creates;

  5     private int loads;

  6

  7     public void onDelete(Object entity,

  8                          Serializable id,

  9                          Object[] state,

 10                          String[] propertyNames,

 11                          Type[] types) {

 12         // do nothing

 13     }

 14

 15     public boolean onFlushDirty(Object entity,

 16                                 Serializable id,

 17                                 Object[] currentState,

 18                                 Object[] previousState,

 19                                 String[] propertyNames,

 20                                 Type[] types) {

 21

 22         if (entity instanceof Auditable) {

 23             updates++;

 24             for (int i = 0; i < propertyNames.length; i++) {

 25                 if ("lastUpdateTimestamp".equals(propertyNames[i])) {

 26                     currentState[i] = new Date();

 27                     return true;

 28                 }

 29             }

 30         }

 31         return false;

 32     }

 33

 34     public boolean onLoad(Object entity,

 35                           Serializable id,

 36                           Object[] state,

 37                           String[] propertyNames,

 38                           Type[] types) {

 39         if (entity instanceof Auditable) {

 40             loads++;

 41         }

 42         return false;

 43     }

 44

 45     public boolean onSave(Object entity,

 46                           Serializable id,

 47                           Object[] state,

 48                           String[] propertyNames,

 49                           Type[] types) {

 50

 51         if (entity instanceof Auditable) {

 52             creates++;

 53             for (int i = 0; i < propertyNames.length; i++) {

 54                 if ("createTimestamp".equals(propertyNames[i])) {

 55                     state[i] = new Date();

 56                     return true;

 57                 }

 58             }

 59         }

 60         return false;

 61     }

 62

 63     public void afterTransactionCompletion(Transaction tx) {

 64         if (tx.wasCommitted()) {

 65             System.out.println("Creations: " + creates + ", Updates: " + updates+ "Loads: " + loads);

 66         }

 67         updates = 0;

 68         creates = 0;

 69         loads = 0;

 70     }

 71

 72 }

 

 

2.         事件系统(Event system)

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

基本上,Session接口的每个方法都有相对应的事件。比如 LoadEventFlushEvent,等等(可以查阅XML配置文件 DTD以及org.hibernate.event包来获得所有已定义的事件的列表)。

当某个方 法被调用时,Hibernate Session会生成一个相应的事件并激活所有配置好的事件监听器。被监听的方法所做的其实仅仅是激活监听器,“实际”的工作是由监听器完成的。你可以自由地选择实现一个自己定制的监听器:比如,实现并注册用来处理处理LoadEventLoadEventListener接口, 来处理所有的调用Sessionload()方法的请求。

监听器在运行时被实例化为单例(singleton)对象,也就是说,所有同类型的事件的处理共享同一个监听器实例,因此监听器不应该保存任何与请求相关的状态。

用户定制的监听器需要实现相关的事件监听器接口,或者从一个合适的基类继承(甚至是从Hibernate自带的默认事件监听器类继承,作者已经通过这些类的non-final定义给予我们这样的暗示和权利了)。

用户定制的监听器可以通过编程使用Configuration对象 来注册,也可以在HibernateXML格式的配置文件中进行声明(不支持在Properties格式的配置文件声明监听器)。 下面是一个用户定制的加载事件(load event)的监听器:

public class MyLoadListener implements LoadEventListener {

    // this is the single method defined by the LoadEventListener interface

    public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType)

                          throws HibernateException {

       if ( !MySecurity.isAuthorized( event.getEntityClassName(), event.getEntityId() ) ) {

            throw MySecurityException("Unauthorized access");

       }

    }

}

 

除此之外你还需要修改一处配置,来告诉Hibernate,除了默认的监听器,还要附加选定的监听器。

<hibernate-configuration>

    <session-factory>

        ...

        <event type="load">

            <listener class="com.eg.MyLoadListener"/>

            <listener class="org.hibernate.event.def.DefaultLoadEventListener"/>

        </event>

    </session-factory>

</hibernate-configuration>

看看用另一种方式,通过编程的方式来注册它。

Configuration cfg = new Configuration();

LoadEventListener[] stack = { new MyLoadListener(), new DefaultLoadEventListener() };

cfg.EventListeners().setLoadEventListeners(stack);

 

通过在XML配置文件声明而注册的监听器不能共享实例。如果在多个<listener/>节点中使用 了相同的类的名字,则每一个引用都将会产生一个独立的实例。如果你需要在多个监听器类型之间共享 监听器的实例,则你必须使用编程的方式来进行注册。

 

为什么我们实现了特定监听器的接口,在注册的时候还要明确指出我们要注册哪个事件的监听器呢? 这是因为一个类可能实现多个监听器的接口。在注册的时候明确指定要监听的事件,可以让启用或者禁用对某个事件的监听的配置工作简单些。

 

当与Spring配合使用时同样需要配置sessionFactoryeventListener属性。

分享到:
评论
5 楼 raymond2006k 2008-11-24  
betafox 写道
关于拦截器还有一个例子一直加不进去,只要加上那个例子文章一提交就出错!


可以附在回复里。
文章写的不错,很有用的资料。
4 楼 liucl_tiger 2008-11-07  
我也正学习这个!
3 楼 taupo 2008-09-02  
我们的项目中用拦截器来删除帖子的附件。。。
我感觉这是一种比较好的利用拦截器

2 楼 betafox 2008-08-28  
希望能发掘一下大家对hibernate拦截器的使用。
1 楼 betafox 2008-08-28  
关于拦截器还有一个例子一直加不进去,只要加上那个例子文章一提交就出错!

相关推荐

    Hibernate5中文用户使用手册

    拦截器和事件:这部分内容介绍了拦截器(Interceptors)以及原生事件系统和JPA回调的使用。 HQL与JPQL:Hibernate Query Language (HQL)和Java Persistence Query Language (JPQL)是Hibernate用于查询数据的语言。...

    hibernate 体系结构与配置 参考文档(html)

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    Hibernate5用户手册中文版

    12. 拦截器和事件章节,介绍了拦截器(Interceptors)的使用,Hibernate声明式安全的配置,以及JPA回调的处理。 13. HQL与JPQL章节,详细说明了Hibernate查询语言(HQL)和Java持久化查询语言(JPQL)的语法、大小写...

    hibernate3.5完整jar

    7. **事件监听器**:Hibernate 3.5支持事件监听机制,允许开发者注册监听器来拦截特定的持久化操作,如保存、更新、删除等,从而实现自定义的业务逻辑。 8. **级联操作**:在关联映射中,可以设置级联操作,比如在...

    Hibernate5 的用户手册中文版

    12. 拦截器和事件: 介绍了拦截器的使用和配置,Hibernate的声明式安全机制,以及JPA的回调接口。 13. HQL与JPQL: 说明了Hibernate查询语言(HQL)和Java持久化查询语言(JPQL)的使用,包括大小写敏感性,语句...

    Hibernate学习.pdf

    - **拦截器**: 用于拦截某些事件并执行特定逻辑。 #### 12. 批处理(Batch Processing) - **批量插入(Batch Inserts)**: 提高批量插入数据的效率。 - **批量更新(Batch Updates)**: 提高批量更新数据的效率。...

    ssh框架用struts2 hibernate实现图片的上传源码

    1. **Struts2**:Struts2是一个基于MVC设计模式的Web应用框架,它通过拦截器模型来处理用户的请求。在图片上传的场景中,Struts2提供Action类来接收用户上传的图片文件,同时可以通过配置Struts2的配置文件(struts....

    整合Spring3.1.0.RC1,Struts2.2.3和Hibernate3.2三大框架所需jar包

    - **拦截器**:Struts2的核心是拦截器,它们可以插入到Action调用链中,实现AOP功能,如验证、日志记录和性能监控。 - **插件体系**:Struts2支持丰富的插件,如Struts2-convention、Struts2-dojo等,提供额外的...

    spring3.1.1+struts2.3.1+hibernate3.3.2

    Struts2的配置文件(struts.xml)会配置Action和拦截器,而Hibernate的配置文件(hibernate.cfg.xml)会设定数据库连接信息和实体类映射。通过Spring的AOP,可以实现事务的声明式管理,确保数据操作的一致性。 在...

    hibernate shards中文文档

    - **拦截器限制**:说明了在使用有状态拦截器时需要注意的事项。 ##### 6.5 标识符 (Ids) 是基础类型的对象 - **标识符类型**:强调了在水平分片环境下标识符应当使用基本数据类型的重要性。 ##### 6.6 冗余数据 ...

    strut2+hibernate+mysql的实例

    它提供了丰富的拦截器和插件体系,能够方便地进行表单验证、数据绑定和异常处理。在本实例中,你将看到Struts2如何定义Action类,接收并转发用户请求,以及如何配置struts.xml来定义URL映射和处理逻辑。 Hibernate...

    Hibernate框架参考文档

    12. 拦截器与事件(Interceptors and events); 13. 批量处理(Batch processing; 14. HQL: Hibernate查询语言; 15. 条件查询(Criteria Queries); 16. Native SQL查询; 17. 过滤数据; 18. XML映射; 19. 提升性能; 20. ...

    hibernate和struts2.1.6 包

    Struts2提供了强大的控制层,它通过拦截器机制实现了请求的处理,使得开发者可以灵活地定义业务逻辑流程。它的Action类是处理用户请求的核心,每个Action对应一个特定的业务操作。Struts2还支持OGNL(Object-Graph ...

    Hibernate+中文文档

    12. 拦截器与事件(Interceptors and events) 12.1. 拦截器(Interceptors) 12.2. 事件系统(Event system) 12.3. Hibernate的声明式安全机制 13. 批量处理(Batch processing) 13.1. 批量插入(Batch inserts) ...

    java学习hibernate

    第8节-拦截器和事件.ppt会讲解Hibernate的事件监听器和拦截器机制,它们允许自定义行为,比如在对象保存、更新或删除时进行额外的操作。 `HibernateUtil.java`文件可能是Hibernate的工具类,通常包含...

    框架lib补充包括struts和hibernate

    Struts 2是其升级版,提供了更强大的功能,如更多类型的拦截器、更灵活的动作配置和插件体系。 Hibernate则是一个强大的ORM工具,它允许开发者用面向对象的方式来处理数据库操作。通过Hibernate,我们可以定义对象...

    struts2+spring+hibernate示例

    Struts2、Spring和Hibernate是Java Web开发中的三大框架,它们各司其职,共同构建了一个强大的企业级应用体系。这个示例项目是基于这三个框架的整合应用,用于实现一个基本的用户登录功能。 **Struts2** 是一个用于...

    Hibernate API.rar

    九、事件监听和拦截器 Hibernate提供了一套事件监听机制,允许我们在特定的数据库操作前后执行自定义逻辑。同时,拦截器(Interceptor)提供了更细粒度的控制,可以在Session级别的操作前、后,甚至每个单独的持久...

    Spring,hibernate,Struts2的官方文档

    Struts2支持多种结果类型和拦截器,可以实现权限验证、日志记录等功能。它有丰富的插件体系,可以集成其他框架如Spring、Hibernate。Struts2的FreeMarker和Velocity模板技术,让视图层的开发更加便捷。此外,Struts2...

    struts2、spring、hibernate面试题集

    Struts2的核心是Action和Result,它通过拦截器(Interceptor)链来处理请求,实现了MVC设计模式。 2. Struts2如何实现Action的跳转? 使用Result类型定义结果页面,如dispatcher(默认)或stream等,根据Action...

Global site tag (gtag.js) - Google Analytics