`

Hibernate拦截器与事件监听

阅读更多

拦截器(Interceptor)
org.hibernate.Interceptor接口定义了Hibernate中通用拦截机制
创建Session对象的时候,所有的Session对象或者这个Session对象的所有持久化操作的动作都会被指定的拦截器进行拦截.


Interceptor接口的方法

  • afterTransactionBegin()
    当一个事务时候启动时,会立刻调用这个方法,这个方法可以改变这个事务的状态,例如:回滚事务
  • instantiate()
    创建对象,如果返回null,则Hibernate将调用实体类的默认构造方法创建持久化对象
  • getEntity()
    当一个持久化对象,通过标示符属性在Session对象的缓存中进行查找,并且没有找到时,会调用该方法
  • getEntityName()
    当session对象获取持久化对象的名字时,会调用这个方法
  • onLoad()
    该方法在持久化对象初始化之前加载,这个的持久化对象处于刚被创建的状态(对象的属性值都未赋值)
  • findDirty()
    当调用Session对象的flush()方法时,讲调用该方法判断对象是否为脏数据,这是脏数据检查的另外拦截的实现方式
  • isTransient()
    当调用Session对象的saveOrUpdate方法时,会调用该方法判断对象是否尚未保存
  • onSave()
    在对象被保存之前调用,通过这个方法可以对要保持的对象的属性进行修改
  • onDelete()
    该方法在持久化对象被删除之前调用
  • preFlush()
    该方法当调用Session对象的flush()方法之前被调用
  • onFlushDirty()
    当调用Session对象flush()方法进行脏数据检查时,如果发现持久化对象的状态发生了改变,会调用该方法
  • postFlush()
    该方法调用Session对象的flush()方法之后被调用
  • beforeTransactionCompletion()
    在完成一个事务之前,调用此方法,这个方法可以改变事务的状态,例如回滚事务
  • afterTransactionCompletion()
    当完成一个事务之后,立刻调用此方法

1、使用拦截器实现操作日志
在应用系统中,对所有的数据库的操作都做记录,记录所操作内容,操作的用户和操作的时间

 

import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

import java.io.Serializable;
import java.util.Date;


public class DaoLogInterceptor extends EmptyInterceptor {

	private static final long serialVersionUID = 1L;

	@Override
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        super.onDelete(entity, id, state, propertyNames, types);
    }

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        return super.onSave(entity, id, state, propertyNames, types);
    }

    @Override
    public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {
        super.onCollectionUpdate(collection, key);
    }

    @Override
    public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {
        super.onCollectionRemove(collection, key);
    }

    @Override
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        return super.onLoad(entity, id, state, propertyNames, types);
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
    	System.out.println("operateTm:"+entity.getClass().getName()+"--OperateTm:"+new Date()+"--操作用户:当前登录用户");
    	getOperateDetails(previousState, currentState, propertyNames);
        return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
    }


    /**
     * 操作前后的数据差异
     *
     * @param oldState
     * @param state
     * @param operateLog
     * @return
     */
    private void getOperateDetails(Object[] oldState, Object[] state, String[] propertyNames) {
        for (int i = 0; i < propertyNames.length; i++) {
            if (!equalsObject(oldState[i], state[i])) {
                System.out.println("Field:"+propertyNames[i]+"NewValue:"+state[i] +"OldValue:"+oldState[i]);
            }
        }
    }

    private boolean equalsObject(Object o1, Object o2) {
        if (o1 == null && o2 != null) {
            return false;
        }
        if (o2 == null && o1 != null) {
            return false;
        }
        if (o1 == null && o2 == null) {
            return true;
        }
        return o1.equals(o2);
    }
}

 

 

 

<!--hibernate配置-->

    <bean id="myInterceptor" class="com.sf.sfbuy2.context.filter.DaoLogInterceptor"/>
    <bean id="postUpdateListener" class="com.sf.sfbuy2.context.filter.PostUpdateListener"></bean>
    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="entityInterceptor">
            <ref bean="myInterceptor" />
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="use_sql_comments">true</prop>
                <prop key="javax.persistence.validation.mode">none</prop>
                <prop key="hibernate.validator.apply_to_ddl">false</prop>
                <prop key="hibernate.validator.autoregister_listeners">false</prop>

            </props>
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.sf.sfbuy2.db.entity</value>
            </list>
        </property>
    </bean>

2、Hibernate的事件监听机制

 

Hibernate中的事件监听机制可以对Session对象的动作进行监听,一旦发生了特殊的事件,Hibernate就会执行监听器中的事件处理方法

在某些功能的设计中,我们即可以使用Hibernate的拦截器实现,也可以使用Hibernate的事件监听来实现

 

Hibernate中事件与对应的监听器接口

                 事件类型                                                       监听器接口

                     auto-flush                                                    AutoFlushEventListener
                        merge                                                       MergeEventListener
                        delete                                                       DeleteEventListener
                        persist                                                      PersistEventListener
                    dirty-check                                                    DirtyCheckEventListener
                         evice                                                        EvictEventListener
                          flush                                                        FlushEventListener
                    flush-entity                                                    FlushEntityEventListener
                          load                                                         LoadEventListener
                 load-collection                                                  InitializeCollectEventListener
                          lock                                                          LockEventListener
                      refresh                                                         RefreshEventListener
                      replicate                                                      ReplicateEventListener
                     save-update                                                 SaveOrUpdateEventListener
                     pre-load                                                        PreLoadEventListener
                     pre-update                                                    PreUpdateEventListener
                     pre-delete                                                     PreDeleteEventListener
                     pre-insert                                                      PreInsertEventListener
                     post-load                                                       PostLoadEventListener
                     post-update                                                   PostUpdateEventListener
                     post-delete                                                    PostDeleteEventListener
                     post-insert                                                     PostInsertEventListener

 


应用Hibernate事件监听器

用户制定的事件监听器首先需要实现与所需要处理的事件对应的接口,或者继承实现这个接口的类

通过使用Hibernate的配置文件(hibernate.cfg.xml)配置事件监听对象,或者使用Configuration对象注册这个定制的事件监听器对象

LogPostLoadEventListener

 

import org.hibernate.event.PostLoadEvent;
import org.hibernate.event.PostLoadEventListener;
public class LogPostLoadEventListener implements PostLoadEventListener {
	private static final long serialVersionUID = 404241098418965422L;
	public void onPostLoad(PostLoadEvent event) {
		System.out.println("Class:" + event.getEntity().getClass().getName() + ",id:"
				+ event.getId());
	}
}

修改Hibernate.cfg.xml文件

<mapping resource="com/rbh/examples/Guestbook.hbm.xml" />
		<listener type="post-load" class="com.rbh.examples.LogPostLoadEventListener" />
	</session-factory>
</hibernate-configuration>

 或者通过Configuration 对象注册这个监听器对象

Configuration config = new Configuration();
config.setListener("post-load", new LogPostLoadEventListener());
config.configure();
Session session = config.buildSessionFactory().getCurrentSession();

 

编写、配置好监听器以后,当通过Session对象的load()、get()方法或者Query对象的list方法加载持久化对象之后,LogPostEventListener对象中的onPostLoad()方法就会被执行.

 

使用监听器实现记录操作日志

利用Hibernate的事件机制,不仅能够精确追踪到持久化对象的字段的修改,持久化对象关联关系的变更,还能记录更新前的数值和更新后的数值

 

监听器与拦截器的比较

监听器可以实现更细化粒度的拦截
通过监听器获取所拦截的持久化对象的修改后喝修改前的状态值
能直接通过Event对象获取Session对象

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    拦截器和控制器的区别

    拦截器和过滤器的区别 1、拦截器基于动态代理 , 过滤器基于函数回调 2、拦截器不依赖于servlet容器,通过动态代理实现,过滤器依赖于servlet容器 3、拦截器在方法前后,异常前后等调用,而过滤器只能在请求前和请求...

    Hibernate实战(第2版 中文高清版)

     12.3.2 拦截Hibernate事件   12.3.3 内核事件系统   12.3.4 实体监听器和回调   12.4 小结   第13章 优化抓取和高速缓存   13.1 定义全局抓取计划   13.1.1 对象获取选项   13.1.2 延迟的默认抓取...

    前后台管理系统模板源代码 java语言 ssh开发框架 Spring+Struts+Hibernate

    又实现了权限拦截器、项目监听器、单元测试等功能。 页面简洁大气美观,系统耦合度小,可配置度高,几乎包含了全部常用功能,是很好的学习和使用框架,可直接部署测试。 项目访问路径:...

    java后台框架源码

    filter:Log4jFormatFilter(格式化log4j日志输出的),SessionCheckFilter(登陆拦截器) interceptor:权限拦截包 listener:目前只有session的监听器,用于监听session的 service:具体的业务处理包 util:项目工具包 ...

    从J2SE到J2EE知识点介绍

    1. struts2的拦截器定义以及使用 153 2. struts标签 160 3. Struts 2 标签库说明及使用 160 4. set 描述 169 5. text 描述 170 6. property 描述 170 7. Struts的异常处理 171 8. Struts的上传与下载 178 五、 ...

    传智播客黑马35期

    day30_struts2拦截器&ognl;表达式 day31_struts2数据验证&常用标签 day32_struts2编码实战 day33_hibernate01 day34_hibernate02 day35_hibernate03 day36_hibernate04 day37_spring01 day38_spring02 day...

    从零开始学Spring Boot

    1.25 Spring Boot 拦截器HandlerInterceptor 1.26 Spring Boot启动加载数据CommandLineRunner 1.27 Spring Boot环境变量读取和属性对象的绑定 1.28 Spring Boot使用自定义的properties 1.29 改变自动扫描的包 1.30 ...

    spring in action英文版

     11.1.1 安全拦截器  11.1.2 认证管理器  11.1.3 访问决策管理器  11.1.4 运行身份管理器  11.2 管理身份验证  11.2.1 配置ProviderManager  11.2.2 根据数据库验证身份  11.2.3 根据LDAP...

    ssh对lob完美处理

    structs1.2 spring2.5 hibernate3.0 java web 对clob大文本 blob图像处理 这是一个完整的例子,整合了ckeidtor,servlet直接显示...配置了监听器,SPRING事物管理,structs1.2拦截器配置 如果有疑问联系QQ:766591490

    Spring in Action(第2版)中文版

    11.3.4使用注释声明拦截器 11.4小结 第12章访问企业服务 12.1从jndi中获取对象 12.1.1使用传统的jndi 12.1.2注入jndi对象 12.1.3在spring2中注入jndi对象 12.2发送电子邮件 12.2.1配置邮件发送器 12.2.2...

    Spring in Action(第二版 中文高清版).part2

    11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送...

    Spring in Action(第二版 中文高清版).part1

    11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入JNDI对象 12.2 发送电子邮件 12.2.1 配置邮件发送...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    8.8 拦截器 332 8.9 依赖注入 335 8.9.1 EJB注入 336 8.9.2 资源注入 339 8.10 配置EJB引用 340 8.11 使用计时器进行任务调度 342 8.12 本章小结 345 第9章 消息驱动EJB 346 9.1 JMS和EJB 347 9.1.1 为什么使用MDB ...

    Spring.3.x企业应用开发实战(完整版).part2

    15.7.2 装配拦截器 15.7.3 异常处理 15.8 小结 第5篇 测试及实战 第16章 实战型单元测试 16.1 单元测试概述 16.1.1 为什么需要单元测试 16.1.2 单元测试之误解 16.1.3 单元测试之困境 16.1.4 单元测试基本概念 16.2...

    Spring3.x企业应用开发实战(完整版) part1

    15.7.2 装配拦截器 15.7.3 异常处理 15.8 小结 第5篇 测试及实战 第16章 实战型单元测试 16.1 单元测试概述 16.1.1 为什么需要单元测试 16.1.2 单元测试之误解 16.1.3 单元测试之困境 16.1.4 单元测试基本概念 16.2...

    Java学习笔记-个人整理的

    {1.4.1}整数与浮点数}{23}{subsection.1.4.1} {1.4.1.1}浮点数原理}{24}{subsubsection.1.4.1.1} {1.4.2}格式化输出浮点数}{24}{subsection.1.4.2} {1.4.3}\texttt {char}}{24}{subsection.1.4.3} {1.4.4}转义...

    Guns系统技术文档及视频

    │ │ │ ├─core----------------项目运行的核心依靠(例如aop日志记录,拦截器,监听器,guns模板引擎,shiro权限检查等) │ │ │ │ │ │ │ ├─modular----------------项目业务代码 │ │ │ │ │ │ │ ├─...

    Spring中文帮助文档

    13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...

Global site tag (gtag.js) - Google Analytics