- 浏览: 7252717 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
项目采用Spring构建,持久层技术采用的是 JPA规范 + Hibernate实现的方案
要实现审计日志的需求,我试用了多种技术方案,最终确定了采用Hibernate 3的新特性事件驱动架构来解决:
技术选型:
- 最土的,在所有的Dao方法中显示的编写日志记录代码
该项目以前是用.net这么干的,这种做法重复工作量太大,维护性差,并且也没实现字段级变更的记录,根本不予考虑。
- 数据库触发器 - 与数据库耦合
与数据库耦合,违背了使用hibernate的初衷,也不予考虑
- 原生的Hibernate Interceptor
优点:可以在hibernate对象操作的时候获取最为详细的运行期信息,字段名,原始值,修改后值等等。
缺点:在JPA API的封装下很难获取到hibernate的session,不能进行持久化操作。
- JPA callback / event-listener
优点:JPA规范,最为优雅简单
缺点:功能太弱,不能满足需求
- 很自然地,干这种事AOP似乎比较合适
优点:灵活,在spring容器中,可以访问所有spring bean
缺点:不能获取详细的运行期信息(字段名,原始值,等等),无法感知hibernate的事务执行,即使dao事务rollback,仍然会插入一条操作历史记录,破坏了“操作”和“历史”的一致性。
-
采用Hibernate 3的新特性 Event-listener
可以解决以上所有问题
能够取得运行期详细信息,除了能记录粗粒度的实体的保存删除操作外,还能精确追踪对实体字段修改、实体关联/级联关系的变更,能记录更新前的值、更新后的值,可以生成详细日志。
灵活解耦,跨数据库,不影响原有代码。
Hibernate3 新特性事件处理框架是hibernate 2拦截器的一个补充或者替代,由拦截器被动拦截操作事件变成事件源的主动驱动,这是一个进步。Hibernate 事件框架官方文档.
Hibernate3中定义了很多的事件,涵盖了持久化过程中不同的生命周期。简单说Session的一个方法(load, flush...)分别对应一个事件,当该方法被调用时,就会触发一个相应的事件,这个事件会被我们预先定义的事件监听器收到,再进行相应的处理。这种方式来做审计日志是再适合不过。
但也有个缺点就是这样的Event-listener是脱离主容器(比如Spring IoC环境)单独实例化的,无法访问主容器的资源(比如要取得当前登录的用户信息就会比较麻烦)。这个暂时还没解决。
在这里我们选取PostInsertEventListener(插入后事件),PostUpdateEventListener(更新后事件),PostDeleteEventListener(删除后事件)接口作为CRUD方法的监听接口。hibernate3中事件是分为pre和post,表示该发生事件前、后。这里我们全部用Post,因为PostEvent只有在数据实际改变后才会触发,假如CRUD事务因为异常回滚,则不会触发事件。
首先定义一个mark接口Historiazable,实现该接口的entity类表明是需要做审计日志的。
然后编写我们自定义的EventListener类,实现上述的事件接口。
在事件接口实现方法里在根据不同的事件编写审计日志的代码。
public class HistoryListener implements PostInsertEventListener,
PostUpdateEventListener, PostDeleteEventListener {
@Override
public void onPostInsert(PostInsertEvent event) {
if (event.getEntity() instanceof Historizable) {
// 保存 插入日志
}
}
@Override
public void onPostUpdate(PostUpdateEvent event) {
if (event.getEntity() instanceof Historizable) {
// 保存 修改日志
}
}
@Override
public void onPostDelete(PostDeleteEvent event) {
if (event.getEntity() instanceof Historizable) {
// 保存 删除日志
}
}
}
配置EventListener
编辑hibernate.cfg.xml,配置监听器
<session-factory>
<listener type="post-insert" class="net.jeffrey.hibernate.history.HistoryListener"/>
<listener type="post-update" class="net.jeffrey.hibernate.history.HistoryListener"/>
<listener type="post-delete" class="net.jeffrey.hibernate.history.HistoryListener"/>
</session-factory>
配置持久化单元
在persistence.xml中加入
<property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml"/>
这样JPA环境启动后,就会正确装载初始化自定义的事件监听器。
源代码:
详细的代码请下载源代码,有完整的注释和单元测试用例,一看就明白了。
为了简便起见,没有建立spring或者ejb3项目,使用的是POJO方式,但都是一样的。
在源码根目录里的data.sql是为单元测试准备的基础数据,请在测试前导入到数据库中
源码是Netbeans项目,需要添加Hibernate的依赖和mysql驱动
在http://www.hibernate.org/6.html 下载最新版的Hibernate Core, Hibernate Annotations和
Hibernate EntityManager。解压缩后将lib里所有的jar添加到项目中(注意不要把ant相关jar添加进去,可能会导致netbeans无法正常构建项目)。
发表评论
-
【转】在项目中使用多个数据源-多sessionFactory方案
2013-05-10 16:30 3070适用范围:适合SSH架构访问多个数据库, ... -
Hibernate使用中从数据库到模型的加载方式研究
2010-01-28 13:19 1920在项目中数据库中账单Bill一个字段是有多个订单id的以逗 ... -
hibernate中@Transient的使用
2010-01-19 15:20 10637项目中可能有许多实体的需要辅助的属性和方法辅助,hibe ... -
关于hibernate中注解和hbm共存时的加载规律
2010-01-19 15:13 3759项目中使用Spring2.5+hibern ... -
hibernate查询的使用的点滴积累
2010-01-09 13:04 1872/** * 前台查询酒店的级别,设备,类型 * * ... -
Hibernate 的HQL中一个经典函数elements的使用
2010-01-09 12:53 10303在传递索引和元素给集合时(elements and indic ... -
Hibernate关联查询中with的经典使用
2010-01-09 12:42 2160在项目采用Hibernate关联,采用关联使用比较简单,在关 ... -
判断数据库表每条记录中时间段是否在每一个时间段中
2010-01-09 12:35 3039项目中一个成品价格表,每条记录中的价格有一个使用时间 ... -
JPA 中注解一个父类中多个子类实现查询部分子类方法解决方法
2010-01-09 12:10 2023父类: @Entity@Inheritance(stra ... -
Hibernate调用执行存储过程
2010-01-09 12:03 1990项目中需要采用存 ... -
Hibernate的一个异常的解决方案
2009-12-05 11:01 2403在项目中使用HQL时的遇有多个类的嵌套比较发生的异常: ... -
Hibernate的事件和拦截器体系
2009-12-01 13:53 2319持久层框架底层的拦截器机制是对诸如Spring等业务管理容器拦 ... -
Hibernate的拦截器和监听器
2009-12-01 13:52 1924最近项目需要,用到了Hibernate的拦截器和监听器,有些小 ... -
Hibernate的注解many-to-one
2009-11-28 12:12 23234項目中一個實例: ... -
Hibernate查询语言HQL 八大要点
2009-11-18 13:15 1973本文讲述Hibernate查询语言HQL。Hibernat ... -
条件查询(Criteria Queries
2009-11-18 13:14 1726... -
Hibernate查询语言(Query Language), 即HQL
2009-11-18 13:05 2433Hibernate查询语言(Query L ... -
Hibernate中的配置属性
2009-11-15 17:40 1721hbm2ddl.auto的使用配置说明: <!-- ... -
Hibernate JPA 的索引的使用
2009-11-15 17:30 11844在Hibernate中Model中一个对象关 ... -
Hibernate缓存性能监听
2009-11-15 17:23 1655Statistics接口提供三种类别的统计信息: ...
相关推荐
拦截器和过滤器的区别 1、拦截器基于动态代理 , 过滤器基于函数回调 2、拦截器不依赖于servlet容器,通过动态代理实现,过滤器依赖于servlet容器 3、拦截器在方法前后,异常前后等调用,而过滤器只能在请求前和请求...
12.3.4 实体监听器和回调 12.4 小结 第13章 优化抓取和高速缓存 13.1 定义全局抓取计划 13.1.1 对象获取选项 13.1.2 延迟的默认抓取计划 13.1.3 理解代理 13.1.4 禁用代理生成 ...
又实现了权限拦截器、项目监听器、单元测试等功能。 页面简洁大气美观,系统耦合度小,可配置度高,几乎包含了全部常用功能,是很好的学习和使用框架,可直接部署测试。 项目访问路径:...
1.25 Spring Boot 拦截器HandlerInterceptor 1.26 Spring Boot启动加载数据CommandLineRunner 1.27 Spring Boot环境变量读取和属性对象的绑定 1.28 Spring Boot使用自定义的properties 1.29 改变自动扫描的包 1.30 ...
day21_监听器 day22_文件上传与下载 day23_基础加强 day24_在线支付&JavaMail; day25_编码实战day01 day26_编码实战day02 day27_编码实战day02 day28_struts2基础 day29_struts2加强 day30_struts2拦截器&...
listener:目前只有session的监听器,用于监听session的 service:具体的业务处理包 util:项目工具包 vo:存放业务结果数据的,响应页面的json对象就存放在里面ResultData类里面 conf文件:系统配置的文件 ...
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 五、 ...
structs1.2 spring2.5 hibernate3.0 java web 对clob大文本 blob图像处理 这是一个完整的例子,整合了ckeidtor,servlet直接显示...配置了监听器,SPRING事物管理,structs1.2拦截器配置 如果有疑问联系QQ:766591490
10.8 实体的生命周期和监听器 444 10.8.1 实体的生命周期与回调事件 444 10.8.2 使用专门的监听器实现回调 448 10.8.3 为全部实体配置默认监听器 450 10.8.4 排除监听器 452 10.9 本章小结 455 第11章 JPA的查询支持...
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...
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...
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 配置邮件发送...
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 配置邮件发送...
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 ...
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 ...
│ │ │ ├─core----------------项目运行的核心依靠(例如aop日志记录,拦截器,监听器,guns模板引擎,shiro权限检查等) │ │ │ │ │ │ │ ├─modular----------------项目业务代码 │ │ │ │ │ │ │ ├─...
\contentsline {chapter}{Contents}{2}{section*.1} {1}Java基础}{17}{chapter.1} {1.1}基本语法}{17}{section.1.1} {1.2}数字表达方式}{17}{section.1.2} {1.3}补码}{19}{section.1.3} {1.3.1}总结}{23}{...
13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. ...