`
limaofa
  • 浏览: 24499 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

JPA + Hibernate 3 CRUD操作历史审计日志的解决方案

阅读更多
关键字: jpa, hibernate, 审计日志, 操作历史, 拦截器, 事件驱动, event listener
我们前段时间有个.net项目需要用j2ee改造,有个需求是要对所有的数据库操作(CRUD)都要做历史记录,要记录操作内容,操作的用户和操作时间。这样的需求称为审计日志 Audit log。

项目采用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) {   
        // 保存 删除日志   
        }   
    }   
}  

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>  

<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无法正常构建项目)。
分享到:
评论

相关推荐

    hibernate4.2.4札包(精简版)

    总的来说,Hibernate 4.2.4精简版札包为开发者提供了一个高效、简洁的ORM解决方案,帮助他们在不涉及复杂配置和额外模块的情况下,专注于核心业务逻辑的开发。对于初学者或小型项目来说,这是一个理想的起点。在实际...

    hibernate-distribution-3.3.2.GA

    - Hibernate社区活跃,提供大量的插件和扩展,如Hibernate Envers(审计日志)、Hibernate Search(全文搜索)等。 - 强大的文档和教程:官方文档详细介绍了各种功能和用法,社区中的问答平台如Stack Overflow提供...

    Java_Spring和Spring Boot课程的实验解决方案.zip

    3. **数据库集成**:使用Spring Data JPA或MyBatis连接数据库,进行CRUD操作,以及事务管理。 4. **Spring AOP实践**:编写切面,实现日志记录、性能监控等功能。 5. **Spring Boot Actuator使用**:监控应用状态,...

    java springboot客户管理系统cms.rar

    2. 日志记录:系统实现了手动添加日志功能,这在系统异常处理和后期审计时十分有用,可以追踪操作历史,提高问题定位效率。 三、关键技术解析 1. SpringBoot:SpringBoot的核心在于自动配置,它通过“起步依赖”...

    spring boot 实战,springboot实战项目,Java源码.zip

    6. **数据访问**:包括 JPA 和 Hibernate 的使用,数据库连接配置,以及如何进行 CRUD 操作。此外,可能还会涉及 NoSQL 数据库如 MongoDB 的集成。 7. **安全**:Spring Security 是 Spring Boot 的默认安全解决...

    springboot120企业级工位管理系统.zip

    同时,SpringBoot Actuator提供了健康检查、指标展示、审计日志等功能,帮助运维人员监控系统的运行状态。 8. 扩展性与可维护性: 为了适应未来的需求变化,系统应遵循模块化设计原则,每个功能模块尽可能独立,...

    springboot学习项目

    5. **Spring Data JPA**:Spring Boot与Spring Data JPA结合,可以方便地实现对关系型数据库的CRUD操作,支持ORM映射,如Hibernate。 6. **Thymeleaf/FreeMarker 模板引擎**:Spring Boot可以与Thymeleaf或...

    spring-and-spring-boot:Spring和Spring Boot课程的实验室解决方案

    3. **数据访问**:结合JPA或MyBatis,实现对数据库的操作,如CRUD、事务管理。 4. **安全控制**:使用Spring Security进行权限控制,包括登录认证、角色授权等。 5. **自动化测试**:利用Spring Boot的测试支持,...

    springboot开发

    9. **Spring Security**:Spring Boot集成了Spring Security,提供了一套强大的安全解决方案,包括身份验证、授权等。 10. **Spring Cloud**:如果你需要构建微服务架构,Spring Cloud提供了服务发现、负载均衡、...

    基于SpringBoot和SpringCloud和Vue的在线代码评委系统源码.zip

    5. **Spring Data JPA**:提供了与数据库交互的抽象层,支持ORM(对象关系映射)框架如Hibernate,简化了CRUD操作。 6. **Actuator**:提供了健康检查、审计、指标、日志等监控和管理应用的工具。 转向SpringCloud...

    (免费分享)springboot,vue宿舍管理系统-033

    本项目是一个基于SpringBoot后端框架和Vue.js前端框架构建的宿舍管理系统,旨在提供一个高效、便捷的宿舍管理解决方案。SpringBoot以其简洁的配置、快速的开发效率以及强大的功能深受开发者喜爱,而Vue.js作为轻量级...

    Spring-Boot:Spring Boot框架的学习

    6. **数据访问**:探索如何连接数据库,使用JPA进行CRUD操作。 7. **Actuator**:了解Actuator提供的各种监控和管理功能。 8. **微服务实战**:尝试用Spring Boot构建微服务,学习如何使用Spring Cloud组件。 9. ...

    spring-boot:弹簧靴练习

    5. ** Spring Data JPA **:简化了与数据库的交互,支持ORM框架如Hibernate,提供统一的CRUD操作API。 6. ** Spring MVC **:用于构建Web应用程序,支持RESTful风格的控制器。 7. ** YAML/Properties配置 **:灵活的...

    springboot

    它支持多种数据库,如JPA、Hibernate、MyBatis等,通过Repository接口,开发者可以便捷地实现CRUD操作。 8. **Spring Security** SpringBoot集成了Spring Security,提供了一套完整的安全解决方案,包括身份验证、...

    Java-Spring-API

    8. **Spring Security**:如果涉及到权限控制,Spring Security可以提供一套完整的安全解决方案,包括身份验证、授权等。 9. **Actuator**:Spring Boot Actuator提供了一系列端点,用于监控和管理应用程序,包括...

Global site tag (gtag.js) - Google Analytics