hibernate监听器的应用
这里是我看到的一个hibernate监听器的简单实现供参考 http://www.360doc.com/content/14/0623/11/8072791_389034447.shtml
设计思路:
首先,提供一个接口,我们监听实体变化其实需要的就是监听实体增删改的过程,这里我们提供的参数EntityImpl时我们系统业务类的顶层实现(相信我们每个公司的产品都会有一个顶层类),然后是一个记录操作日志的实体类History。
public interface IHistoryListenerProcess {
public void postInsert(EntityImpl operateObject,History history);
public void preDelete(EntityImpl operateObject,History history);
public void postUpdate(EntityImpl operateObject,History history);
}
这个history的参数并不全,相信每个系统也都各异,但是共有的方法还是有一些的
public class History extends SysEntity { private static final long serialVersionUID = 6727254578815488286L; public static final String SEPERATOR = "⑧"; private String dataId;
@Meaning("操作人ID")
private String operatorId;
@Meaning("操作人名称")
private String operatorName;
@Meaning("操作时间")
private Timestamp operateDate;
@Meaning("操作类型")
private String operateType;
@Meaning("操作属性名")
private String attrDisplayName;
@Meaning("操作属性原值")
private String oldAttrValue;
@Meaning("操作属性新值")
private String newAttrValue;
省略get set
}
/**
* hibernate 事件监听器,对新增,删除,修改事件进行监听
*
*/
@SuppressWarnings({ "serial" })
public class HistoryListener implements PostInsertEventListener, PostUpdateEventListener, PreDeleteEventListener { public final static String SAVE = "1"; // 新增
public final static String DELETE = "2";// 删除
public final static String UPDATE = "3";// 修改 /**
* 监听模式
* <ul>
* <li>on:监听所有</li>
* <li>off:不监听</li>
* <li>如果是以英文逗号隔开的类名,则只监听这些类</li>
* <li>这里我们把需要扩展的监听类放在配置文件中SysUtils.getSysParam只是读取配置文件的方法</li>
* </ul>
*/
private static String mode = SysUtils.getSysParam("hibernate.history.listener.classes", "off");
private static String processClassStr = SysUtils.getSysParam("hibernate.history.listener.processCls");
private static IHistoryListenerProcess process; /**
* 捕获插入事件,并保存到历史记录信息中
*
* @param event 新增事件
*/
public void onPostInsert(PostInsertEvent event) {
Object object = event.getEntity();
if (isListened(object)) {
logHistoryOnSaveOrDelete((EntityImpl) object, SAVE, event.getPersister());
}
} /**
* 捕获删除事件,并保存到历史记录信息中
*
* @param event 删除事件
*/
public boolean onPreDelete(PreDeleteEvent event) {
Object object = event.getEntity();
if (isListened(object)) {
logHistoryOnSaveOrDelete((EntityImpl) object, DELETE, event.getPersister());
}
return false;
} /**
* 捕获修改事件,并保存到历史记录信息中
*
* @param enent 修改 event.getOldState() 存的是原来的数据 格式为 数据的值的顺序排列</br>
* eg: 张三,12,2016..... event.getState() 新的值 排列顺序同上
*
*/
public void onPostUpdate(PostUpdateEvent event) {
Object object = event.getEntity();
if (isListened(object)) {
logHistroyOnUpdate((EntityImpl) object, UPDATE, event.getOldState(), event.getState(), event.getPersister());
}
} /**
* 新增删除的历史信息 这里写在一块主要是因为新增和删除是记录一个状态,并不会记录其他的东西
*
* @param operateObject 被操作字段的对象
* @param operateType 用户操作类型
*/
private void logHistoryOnSaveOrDelete(EntityImpl operateObject, String operateType, EntityPersister persister) {
History history = new History();
history.setDataId(operateObject.getId());
history.setOperateType(operateType);
history.setOperateDate(new java.sql.Timestamp(System.currentTimeMillis()));
getProcess(operateObject, history, operateType);
saveHistory(history);
} /**
* 保存history对象
*
* @param history
*/
private void saveHistory(History history) { } /**
* 获取编辑操作字段的属性名,原值,新增
*
* @param newModel 监听器监听到被操作字段的对象
* @param operateType 用户操作类型
*/
private void logHistroyOnUpdate(EntityImpl newModel, String operateType, Object[] oldStates, Object[] newStates, EntityPersister persister) {
String[] fields = persister.getPropertyNames();// 字段属性值
if (oldStates == null || newStates == null || fields == null || oldStates.length != newStates.length || oldStates.length != fields.length) {
return;
}
String oldValue = "";
String newValue = "";
for (int i = 0; i < fields.length; i++) {
Object newState = newStates[i];
Object oldState = oldStates[i];
if (newState == oldState || (newState != null && newState.equals(oldState))) {
continue;
}
newValue += newState + History.SEPERATOR;// 这里用分割符拆分,方便以后处理
oldValue += oldState + History.SEPERATOR;
} logHistroyOnUpdate(newModel, newValue, oldValue, operateType, persister);
} /**
* 保存修改字段的历史信息
*
* @param operateoperateObjectObject 被操作字段的对象
* @param newValue 被操作字段的新值
* @param oldValue 被操作字段的原值
* @param fieldType 被操作字段的类型
* @param fieldName 被操作字段的属性名字
* @param fieldCategoryName 被操作字段对应的字段
* @param operateType 用户操作类型
*/
public void logHistroyOnUpdate(EntityImpl operateObject, String newValue, String oldValue, String operateType, EntityPersister persister) {
History history = SpringContextUtil.getBean(History.class);
history.setDataId(operateObject.getId());
history.setOperateType(operateType);
history.setOldAttrValue(oldValue);
history.setNewAttrValue(newValue);
history.setOperateDate(new java.sql.Timestamp(System.currentTimeMillis()));
getProcess(operateObject, history, operateType);
saveHistory(history);
} private void getProcess(EntityImpl operateObject, History history, String type) {
String[] classStr = processClassStr.split(",");
for (String clazz : classStr) {
if (StringUtils.isNotBlank(processClassStr)) {
Object po = null;
try {
po = Class.forName(clazz).newInstance();
} catch (Exception e) { } if (IHistoryListenerProcess.class.isInstance(po)) {
process = (IHistoryListenerProcess) po;
} else {
throw new SysException("要监听持久化的类必须继承IHistoryListenerProcess接口");
}
}
if (process == null) {
continue;
}
if (StringUtils.equals(type, SAVE)) {
process.postInsert(operateObject, history);
} else if (StringUtils.equals(type, UPDATE)) {
process.postUpdate(operateObject, history);
} else if (StringUtils.equals(type, DELETE)) {
process.preDelete(operateObject, history);
}
process = null;
}
} /**
* 判断是否为监听的模块,在这里可做处理
*
* @param object 监听到被操作的对象
*/
private boolean isListened(Object object) {
if (EntityImpl.class.isInstance(object) && "on".equals(mode)) {
return true;
}
return false;
}
}
这里 我们只要implements IHistoryListenerProcess 并且把类的全路径写入到配置文件中,在hibernate执行增删改的时候就会走我们的方法,这有点类似于监听者模式的意思,当然我们实现这个类也就会得到我们需要的EntityImpl类;
这个实现只是一个便捷的想法,以后在编码中可能会用到,但是现实是我们系统中并不会只用hibernate,或者说是我们封装好的save、update等方法,如果是jdbctemplate呢,我还需要一个spring监听器,所以这就需要我们编码的规范
和底层代码封装的丰富程度了!
hibernate监听器的应用的更多相关文章
- 利用Hibernate监听器实现用户操作日志
网上搜索发现,实现用户操作日志的方式有:自定义注解方式.Hibernate拦截器方式.Hibernate监听器方式等. 1.自定义注解方式较为麻烦,需要进行操作记录的方法均需要添加注解,但是相对的操作 ...
- Hibernate监听器
Hibernate的事件监听机制 Hibernate中的事件监听机制可以对Session对象的动作进行监听,一旦发生了特殊的事件,Hibernate就会执行监听器中的事件处理方法 在某些功能的设计中, ...
- AES实现财务数据的加密解密存储
需求背景 众所周知,金融行业有各种各样的财务报表,有些报表涉及到公司财务或经营相关的敏感数据,需要进行加密存储,只有掌握密钥的用户才能看到解密后的数据.注意,这里所说的加密并不是针对整个数据库或者表全 ...
- Hibernate拦截器(Interceptor)与事件监听器(Listener)
拦截器(Intercept):与Struts2的拦截器机制基本一样,都是一个操作穿过一层层拦截器,每穿过一个拦截器就会触发相应拦截器的事件做预处理或善后处理. 监听器(Listener):其实功能与拦 ...
- SSH项目web.xml文件的常用配置【struts2的过滤器、spring监听器、解决Hibernate延迟加载问题的过滤器、解决中文乱码的过滤器】
配置web.xml(struts2的过滤器.spring监听器.解决Hibernate延迟加载问题的过滤器.解决中文乱码的过滤器) <!-- 解决中文乱码问题 --> <filter ...
- hibernate的拦截器和监听器
拦截器(Intercept):顾名思义,拦截操作,也就是在Hibernate做出动作之前会调用的方法.如果你有需要在Hibernate操作数据库之前想要做的操作,就需要用到这个东西了. 监听器(Lis ...
- 深入浅出Struts2+Spring+Hibernate框架
一.深入浅出Struts2 什么是Struts2? struts2是一种基于MVC的轻量级的WEB应用框架.有了这个框架我们就可以在这个框架的基础上做起,这样就大大的提高了我们的开发效率和质量,为公司 ...
- Struts2+Spring+Hibernate框架整合总结详细教程
一.SSH三大框架知识总结 Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架.其全新的Struts 2的体系结构与S ...
- Hibernate(4)——主键生成策略、CRUD 基础API区别的总结 和 注解的使用
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: hibernate的主键生成策略 UUID 配置的补充:hbm2ddl.auto属性用法 注解还是配置文件 h ...
随机推荐
- Struts2 05---拦截器
一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,使用了aop思想和责任链模式,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截 ...
- jsp里的逻辑语句c:if和c:choose
1.c:if <c:if test=""></c:if> c:when的test里可以是变量或者是一个EL表达式,其结果应该是true或者false. EL ...
- C#总结(四)调用C++动态库
由于公司很多底层的SDK,都是C++开发,上层的应用软件却是C# Winform程序.在实际工作的过程中,就经常碰到了C# 程序调用C++ 动态库的问题.最近一直在和C++ 打交道,C# 怎么调用C+ ...
- 智能家居esp8266对接机智云
依然存在稳定性问题 机智云官网--机智云 一个比较详细的教程--esp8266 一开始采用的是esp12f 可是他太不稳定,总是掉线,机智云的固件我也是刷了无数遍,哎太难了. 我比较懒,走过了太多 ...
- wamp版本升级小问题记录
在升级wamp版本时遇到的一些小问题,特此记录 在安装完成之后,修改了Apache根目录,可以正常访问.但是发现 httpd-vhosts.conf追加配置的无法访问,逐步检查,有以下问题 1.Inc ...
- Spring Boot:在Spring Boot中使用Mysql和JPA
本文向你展示如何在Spring Boot的Web应用中使用Mysq数据库,也充分展示Spring Boot的优势(尽可能少的代码和配置).数据访问层我们将使用Spring Data JPA和Hiber ...
- Java 中的变量
变量 Java 程序的变量大体可分为成员变量和局部变量. 局部变量 形参:在方法签名中定义的局部变量,由方法调用者负责为其赋值,随方法的结束而消亡. 方法内的局部变量:在方法内定义的局部变量,必须在方 ...
- 捕获arm托管磁盘虚拟机,并进行还原
背景:托管磁盘虚拟机"hlmma69n2",附加了一块100GB的数据磁盘.可以通过Portal管理界面直接捕获该虚拟机并进行还原,详情见如下步骤: 1.在虚拟机内部执行一般化的操 ...
- relative 和 absolute 定位关系
问题: relative 和 absolute 之间的关系是什么?有什么区别? 那,答案呢? relative 相对定位, 以自己没有设置relative 属性之前的位置来定位,占用没有设置rela ...
- python_如何创建可管理的对象属性
案例: 在面向对象编程中,我们把方法作为对象的接口,自己访问对象的属性可能是不安全的,或设计上不灵活,但是使用调用方法在形式上不如访问属性简洁 繁: circle.getRadius() circle ...