博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate监听器的应用
阅读量:5901 次
发布时间:2019-06-19

本文共 8007 字,大约阅读时间需要 26 分钟。

这里是我看到的一个hibernate监听器的简单实现供参考  http://www.360doc.com/content/14/0623/11/8072791_389034447.shtml

设计思路:

首先,提供一个接口,我们监听实体变化其实需要的就是监听实体增删改的过程,这里我们提供的参数EntityImpl时我们系统业务类的顶层实现(相信我们每个公司的产品都会有一个顶层类),然后是一个记录操作日志的实体类History。

1 public interface IHistoryListenerProcess {2     public void postInsert(EntityImpl operateObject,History history);3     public void preDelete(EntityImpl operateObject,History history);4     public void postUpdate(EntityImpl operateObject,History history);5 }

 这个history的参数并不全,相信每个系统也都各异,但是共有的方法还是有一些的

1 public class History extends SysEntity { 2  3     private static final long serialVersionUID = 6727254578815488286L; 4  5     public static final String SEPERATOR = "⑧"; 6  7     private String dataId; 8     @Meaning("操作人ID") 9     private String operatorId;10     @Meaning("操作人名称")11     private String operatorName;12     @Meaning("操作时间")13     private Timestamp operateDate;14     @Meaning("操作类型")15     private String operateType;16     @Meaning("操作属性名")17     private String attrDisplayName;18     @Meaning("操作属性原值")19     private String oldAttrValue;20     @Meaning("操作属性新值")21     private String newAttrValue;22     省略get set    23 }
18  19 /** 20  * hibernate 事件监听器,对新增,删除,修改事件进行监听 21  *  22  */ 23 @SuppressWarnings({ "serial" }) 24 public class HistoryListener implements PostInsertEventListener, PostUpdateEventListener, PreDeleteEventListener { 25  26     public final static String SAVE = "1"; // 新增 27     public final static String DELETE = "2";// 删除 28     public final static String UPDATE = "3";// 修改 29  30     /** 31      * 监听模式 32      * 
    33 *
  • on:监听所有
  • 34 *
  • off:不监听
  • 35 *
  • 如果是以英文逗号隔开的类名,则只监听这些类
  • 36 *
  • 这里我们把需要扩展的监听类放在配置文件中SysUtils.getSysParam只是读取配置文件的方法
  • 37 *
38 */ 39 private static String mode = SysUtils.getSysParam("hibernate.history.listener.classes", "off"); 40 private static String processClassStr = SysUtils.getSysParam("hibernate.history.listener.processCls"); 41 private static IHistoryListenerProcess process; 42 43 /** 44 * 捕获插入事件,并保存到历史记录信息中 45 * 46 * @param event 新增事件 47 */ 48 public void onPostInsert(PostInsertEvent event) { 49 Object object = event.getEntity(); 50 if (isListened(object)) { 51 logHistoryOnSaveOrDelete((EntityImpl) object, SAVE, event.getPersister()); 52 } 53 } 54 55 /** 56 * 捕获删除事件,并保存到历史记录信息中 57 * 58 * @param event 删除事件 59 */ 60 public boolean onPreDelete(PreDeleteEvent event) { 61 Object object = event.getEntity(); 62 if (isListened(object)) { 63 logHistoryOnSaveOrDelete((EntityImpl) object, DELETE, event.getPersister()); 64 } 65 return false; 66 } 67 68 /** 69 * 捕获修改事件,并保存到历史记录信息中 70 * 71 * @param enent 修改 event.getOldState() 存的是原来的数据 格式为 数据的值的顺序排列
72 * eg: 张三,12,2016..... event.getState() 新的值 排列顺序同上 73 * 74 */ 75 public void onPostUpdate(PostUpdateEvent event) { 76 Object object = event.getEntity(); 77 if (isListened(object)) { 78 logHistroyOnUpdate((EntityImpl) object, UPDATE, event.getOldState(), event.getState(), event.getPersister()); 79 } 80 } 81 82 /** 83 * 新增删除的历史信息 这里写在一块主要是因为新增和删除是记录一个状态,并不会记录其他的东西 84 * 85 * @param operateObject 被操作字段的对象 86 * @param operateType 用户操作类型 87 */ 88 private void logHistoryOnSaveOrDelete(EntityImpl operateObject, String operateType, EntityPersister persister) { 89 History history = new History(); 90 history.setDataId(operateObject.getId()); 91 history.setOperateType(operateType); 92 history.setOperateDate(new java.sql.Timestamp(System.currentTimeMillis())); 93 getProcess(operateObject, history, operateType); 94 saveHistory(history); 95 } 96 97 /** 98 * 保存history对象 99 * 100 * @param history101 */102 private void saveHistory(History history) {103 104 }105 106 /**107 * 获取编辑操作字段的属性名,原值,新增108 * 109 * @param newModel 监听器监听到被操作字段的对象110 * @param operateType 用户操作类型111 */112 private void logHistroyOnUpdate(EntityImpl newModel, String operateType, Object[] oldStates, Object[] newStates, EntityPersister persister) {113 String[] fields = persister.getPropertyNames();// 字段属性值114 if (oldStates == null || newStates == null || fields == null || oldStates.length != newStates.length || oldStates.length != fields.length) {115 return;116 }117 String oldValue = "";118 String newValue = "";119 for (int i = 0; i < fields.length; i++) {120 Object newState = newStates[i];121 Object oldState = oldStates[i];122 if (newState == oldState || (newState != null && newState.equals(oldState))) {123 continue;124 }125 newValue += newState + History.SEPERATOR;// 这里用分割符拆分,方便以后处理126 oldValue += oldState + History.SEPERATOR;127 }128 129 logHistroyOnUpdate(newModel, newValue, oldValue, operateType, persister);130 }131 132 /**133 * 保存修改字段的历史信息134 * 135 * @param operateoperateObjectObject 被操作字段的对象136 * @param newValue 被操作字段的新值137 * @param oldValue 被操作字段的原值138 * @param fieldType 被操作字段的类型139 * @param fieldName 被操作字段的属性名字140 * @param fieldCategoryName 被操作字段对应的字段141 * @param operateType 用户操作类型142 */143 public void logHistroyOnUpdate(EntityImpl operateObject, String newValue, String oldValue, String operateType, EntityPersister persister) {144 History history = SpringContextUtil.getBean(History.class);145 history.setDataId(operateObject.getId());146 history.setOperateType(operateType);147 history.setOldAttrValue(oldValue);148 history.setNewAttrValue(newValue);149 history.setOperateDate(new java.sql.Timestamp(System.currentTimeMillis()));150 getProcess(operateObject, history, operateType);151 saveHistory(history);152 }153 154 private void getProcess(EntityImpl operateObject, History history, String type) {155 String[] classStr = processClassStr.split(",");156 for (String clazz : classStr) {157 if (StringUtils.isNotBlank(processClassStr)) {158 Object po = null;159 try {160 po = Class.forName(clazz).newInstance();161 } catch (Exception e) {162 163 }164 165 if (IHistoryListenerProcess.class.isInstance(po)) {166 process = (IHistoryListenerProcess) po;167 } else {168 throw new SysException("要监听持久化的类必须继承IHistoryListenerProcess接口");169 }170 }171 if (process == null) {172 continue;173 }174 if (StringUtils.equals(type, SAVE)) {175 process.postInsert(operateObject, history);176 } else if (StringUtils.equals(type, UPDATE)) {177 process.postUpdate(operateObject, history);178 } else if (StringUtils.equals(type, DELETE)) {179 process.preDelete(operateObject, history);180 }181 process = null;182 }183 }184 185 /**186 * 判断是否为监听的模块,在这里可做处理187 * 188 * @param object 监听到被操作的对象189 */190 private boolean isListened(Object object) {191 if (EntityImpl.class.isInstance(object) && "on".equals(mode)) {192 return true;193 }194 return false;195 }196 }

这里 我们只要implements IHistoryListenerProcess 并且把类的全路径写入到配置文件中,在hibernate执行增删改的时候就会走我们的方法,这有点类似于监听者模式的意思,当然我们实现这个类也就会得到我们需要的EntityImpl类;

这个实现只是一个便捷的想法,以后在编码中可能会用到,但是现实是我们系统中并不会只用hibernate,或者说是我们封装好的save、update等方法,如果是jdbctemplate呢,我还需要一个spring监听器,所以这就需要我们编码的规范

和底层代码封装的丰富程度了!

转载于:https://www.cnblogs.com/sun-space/p/5770754.html

你可能感兴趣的文章
多线程一个错误的例子
查看>>
默认网关及route print
查看>>
Servlet如何处理一个请求?
查看>>
Linux Daily2
查看>>
使用Jquery+CSS如何创建流动导航菜单-Fluid Navigation
查看>>
Office文档出错的几种原因与解决方法
查看>>
【实验报告】实验二:DHCP基本实验
查看>>
气质的培养(哈佛管理世界)
查看>>
Can&#39;t get Kerberos realm
查看>>
正则表达式 学习笔记1.1
查看>>
通过案例学调优之--AWR BaseLine管理
查看>>
如何使用MySQL提升权限
查看>>
keepalived 原理,安装,配置
查看>>
乐在其中设计模式(C#) - 单例模式(Singleton Pattern)
查看>>
Tensorflow官方语音识别入门教程 | 附Google新语音指令数据集
查看>>
AssetBundle进阶内存优化(Unity 4.x)
查看>>
Windows Home Server 简体中文版安装和配置体验 - 海量图鉴
查看>>
GitHub 版本控制 项目托管 00 总体框架
查看>>
Silverlight & Blend动画设计系列五:故事板(StoryBoards)和动画(Animations)
查看>>
Windows 8部署系列PART3:配置WDS服务器环境
查看>>