`
fehly
  • 浏览: 245403 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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()
    当完成一个事务之后,立刻调用此方法

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

demo

log4j.properties

log4j.logger.com.rbh.examples=info,appender1
log4j.appender.appender1=org.apache.log4j.FileAppender
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
log4j.appender.appender1.File=ligfile.txt

LogEntityInterceptor

package com.rbh.examples;
import java.io.Serializable;
import org.apache.log4j.Logger;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

public class LogEntityInterceptor extends EmptyInterceptor {

	private static final long serialVersionUID = 1L;
	
	private Logger logger = Logger.getLogger(LogEntityInterceptor.class);

	public void onDelete(Object entity,Serializable id, Object[] state,String[] propertyNames,
			Type[] types){
		logger.info("删除数据");
	}
	
	public boolean onFlushDirty(Object entity,Serializable id, Object[] currentState,
			Object[] preState,String[] propertyNames,
			Type[] types){
		logger.info("修改数据");
		return false;
	}
	
	public boolean onSave(Object entity,Serializable id, Object[] State,
			String[] propertyNames,
			Type[] types){
		logger.info("保存数据");
		return false;
	}
}

 

HibernateTest

package com.rbh.examples;

import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateTest {
	public static void main(String[] args) 
	{
		HibernateTest test =new HibernateTest();
		test.testInterceptor();
	}		
	
	public void testInterceptor()
	{
		LogEntityInterceptor interceptor=new LogEntityInterceptor();
		Configuration config=new Configuration();
		config.setInterceptor(interceptor);
		config.configure();
		
		SessionFactory sf=config.buildSessionFactory();
		Session session=sf.getCurrentSession();
		
		Guestbook gb= new Guestbook();
		gb.setName("Narcissus");
		gb.setEmail("javac.q@gmail.com");
		gb.setCreatedTime(new Date());
		gb.setPhone("11102121");
		gb.setTitle("test Interceptor");
		gb.setContent("test Interceptor,test Interceptor");

		
		session.beginTransaction();
		session.save(gb);
		session.getTransaction().commit();
		
		session=sf.getCurrentSession();
		gb.setName("tom");
		session.beginTransaction();
		session.update(gb);
		session.getTransaction().commit();
		
		session=sf.getCurrentSession();
		session.beginTransaction();
		session.delete(gb);
		session.getTransaction().commit();
	}
	
}

可以通过session方式加载拦截器对象,也可以通过Configuration对象加载拦截器

Configuration:对所有的session都会被拦截
session:只对当前的session进行拦截

 

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对象

 

 使用监听器实现审计日志的一个demo 见附件

简要说明:AuditLog表式记录 日志的表

AuditLog.java 和AuditLog.hbm.xml表的持久化映射

AuditLogEventListener 具体的实现类

 

分享到:
评论
2 楼 javatozhang 2016-09-14  
讲解的的确不错。很实用。
1 楼 leo_cao 2013-07-24  
很好,很实用

相关推荐

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

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

    拦截器和控制器的区别

    监听器 servlet application /session /request 6/8 个 1、拦截器 定义拦截器的包 定义拦截器的核心 定义拦截器类 &lt;interceptor name="myInterceptor" class="util.MyInterceptor"&gt;&lt;/interceptor&gt; 定义...

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

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

    P6SPY JDBC拦截打印sql语句 非常好的调试工具

    P6spy是一个JDBC Driver的包装工具,p6spy通过对JDBC Driver的封装以达到对SQL语句的监听和分析,以达到各种目的。 p6spy的安装步骤: 1. 下载p6spy的安装包 2. 把p6spy的jar包放到Classpath中,如果是WEB App...

    从J2SE到J2EE知识点介绍

    2. 事件监听 48 (三) I/O输入输出 63 1. 流及输入输出流概述 63 2. File类 64 3. 带缓存的输入输出流 72 4. 序列化 76 (四) 多线程 80 1. 概念与原理 80 2. 两种实现方式 81 3. 生命周期及状态转换 84 4. 线程调度 ...

    java后台框架源码

    entity:hibernate对应的orm与数据库表一一对应的实体类 filter:Log4jFormatFilter(格式化log4j日志输出的),SessionCheckFilter(登陆拦截器) interceptor:权限拦截包 listener:目前只有session的监听器,用于监听...

    传智播客黑马35期

    day22_文件上传与下载 day23_基础加强 day24_在线支付&JavaMail; day25_编码实战day01 day26_编码实战day02 day27_编码实战day02 day28_struts2基础 day29_struts2加强 day30_struts2拦截器&ognl;表达式 ...

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

    12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务处理 12.2.8 延迟加载的问题 12.3 在Spring中使用myBatis 12.3.1 配置SqlMapClient 12.3.2 在Spring配置myBatis ...

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

    12.2.4 添加Hibernate事件监听器 12.2.5 使用原生Hibernate API 12.2.6 使用注解配置 12.2.7 事务处理 12.2.8 延迟加载的问题 12.3 在Spring中使用myBatis 12.3.1 配置SqlMapClient 12.3.2 在Spring配置myBatis ...

    从零开始学Spring Boot

    1.9 JPA - Hibernate 1.10 使用JPA保存数据 1.11 使用JdbcTemplate 1.12 Spring Boot修改端口号 1.13 Spring Boot配置ContextPath 1.14 Spring Boot改变JDK编译版本 1.15 处理静态资源(默认资源映射) 1.16 处理静态...

    spring in action英文版

     2.4.6 监听事件  2.4.7 发布事件  2.4.8 感知其他Bean  2.5 小结  第3章 创建切面  3.1 AOP介绍  3.1.1 定义AOP术语  3.1.2 Spring的AOP实现  3.2 创建通知  3.2.1 前置通知  3.2.2...

    Spring in Action(第2版)中文版

    3.5.5程序事件的解耦 3.5.6让bean了解容器 3.6脚本化的bean 3.6.1给椰子上lime 3.6.2脚本化bean 3.6.3注入脚本化bean的属性 3.6.4刷新脚本化bean 3.6.5编写内嵌的脚本化bean 3.7小结 第4章通知bean 4.1aop...

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

    3.5.5 程序事件的解耦 3.5.6 让Bean了解容器 3.6 脚本化的Bean 3.6.1 给椰子上Lime 3.6.2 脚本化Bean 3.6.3 注入脚本化Bean的属性 3.6.4 刷新脚本化Bean 3.6.5 编写内嵌的脚本化Bean 3.7 小结 第4章 通知...

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

    3.5.5 程序事件的解耦 3.5.6 让Bean了解容器 3.6 脚本化的Bean 3.6.1 给椰子上Lime 3.6.2 脚本化Bean 3.6.3 注入脚本化Bean的属性 3.6.4 刷新脚本化Bean 3.6.5 编写内嵌的脚本化Bean 3.7 小结 第4章 通知...

    Java学习笔记-个人整理的

    {1.4}数据类型}{23}{section.1.4} {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...

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

    10.8.1 实体的生命周期与回调事件 444 10.8.2 使用专门的监听器实现回调 448 10.8.3 为全部实体配置默认监听器 450 10.8.4 排除监听器 452 10.9 本章小结 455 第11章 JPA的查询支持 456 11.1 查询API 457 11.1.1 ...

    ssh对lob完美处理

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

    Spring中文帮助文档

    5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建...

Global site tag (gtag.js) - Google Analytics