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 ...
随机推荐
- Python 之 基础知识(三)
一.函数 def 函数名(): 函数封装的代码 ... def是英文define缩写 别的Python文件可以引入 调用 定义时 和其他代码包括注释保留两个空行 pycharm 调试时 F8 Step ...
- 算法-java代码实现快速排序
快速排序 对于一个int数组,请编写一个快速排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] ...
- Web前端性能优化——如何提高页面加载速度
前言: 在同样的网络环境下,两个同样能满足你的需求的网站,一个"Duang"的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒, ...
- 【开发技术】json
json(JavaScript Object Notation) JavaScript对象符号是一种结构化轻量级的数据传输格式,很多场合替代XML文件格式 JSON格式化校验:http://www.b ...
- Linux IO时事检测工具iostat
Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...
- oracle04_plsql
PLSQL:Procedural Language SQL (1) plsql的基本结构(a) declare id constant number(2):=2;--常量定义 name varchar ...
- 我看过得最易懂的一段AOP的解释
http://blog.csdn.net/zhangliangzi/article/details/51648032 面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ...
- 优化 or 语句
mysql 演示数据库:http://downloads.mysql.com/docs/sakila-db.zip 对于 or 语句,如果要利用索引,则 or 之间的每个条件都必须有索引 renta ...
- java面向对象——类
一.类 类(class)是构造对象的模板或蓝图.由类构造(construct)对象的过程称为创建类的实例(instance). 用 java 编写的所有代码都位于某个类的内部.标准的Java 库提供了 ...
- js随机生成验证码及其颜色
今天迎来了2018年第一场雪,这个美好的日子,总的写点什么纪念一下,在这里写了一个在js中使用Math.random()函数,随机生成四位数的验证码及其验证码换颜色. js代码如下: var arra ...