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 ...
随机推荐
- Spark算子--coalesce和repartition
coalesce和repartition--Transformation类算子 代码示例
- IDC服务器的六大基础知识
无论企业或个人来说,一个是否适合自己的IDC运营商对于业务发展是至关重要的.然而很多用户对IDC行业一知半解,不太了解服务器的种类,更不知道选择什么样的服务器更适合自己了.今天编辑汇总了一些IDC所需 ...
- 织梦CMS提示DedeTag Engine Create File False错误的解决办法总结
今天帮客户升级站点,遇到了一个老问题,生成栏目的时候提示"DedeTag Engine Create File False",突然发觉这个问题竟然在以前做站的时候困扰过我多次,于是 ...
- php网站在服务器上邮件发送不了,在本地可以
标签: php邮箱 2015-11-27 13:58 879人阅读 评论(0) 收藏 举报 分类: php(2) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在做phpmailer发送邮 ...
- 我的flashfxp左右界面怎么变成这样了?
如下图,flashfxp不是说左边是本地的文件夹,右边是服务器上的文件夹的吗?我不懂刚刚怎么搞了一下,变成两边都是服务器上的文件夹了,哪位大神,指点下,谢谢!!! 921050734 | 浏览 168 ...
- 【开发技术】视频URL采集
http://www.joyplus.tv/joypluscms 志精
- winform打开本地html页面
有时候为了提高开发效率和后期可维护性,把cs里面嵌套了远程网页,这样方便后期升级.比如,美图秀秀,qq音乐PC都嵌套了本地和远程网页.在页面拖入控件System.Windows.Forms.WebBr ...
- python_如何修改装饰器中参数?
案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...
- Git知识总览(四) git分支管理之rebase 以及 cherry-pick相关操作
上篇博客聊了<Git知识总览(三) 分支的创建.删除.切换.合并以及冲突解决>,本篇博客我们主要来看一下 rebase 变基相关的操作.rebase 操作和 merge 操作最终都可以达到 ...
- 本篇将记录python开发过程中常见问题
1.Django 外键on_delete的使用 之前用的Django1.8 换成2.0后,出现以下问题: TypeError: init() missing 1 required positional ...