在后端逻辑开发过程中,必然有数据的字段是重复的,是需要保存的,比如当前用户修改了订单,需要记录修改人,修改时间等信息至数据库中,此时没有引用hibernate拦截器时,是需要在每个方法里面都添加对应的代码,记录修改人,修改时间等等字段信息,对这些公用信息每个修改操作都得重复复制,比如在大型电子商务网站中,就必然涉及到很多操作,表结构成百上千,就得在成百上千的后台代码都复制同样的代码进行赋值。
先不说工作量多少,没多少工作量,就是复制下就可。至少这个会多很多不必要的代码,对于系统架构来说,这个就需要在一开始就处理好。此时正好hibernate拦截器就出现了。同时这个拦截器不会对系统造成任何影响,可以随时剔除,同时也不会对框架整体性造成错误影响,完全是个即插即用的。
package com.todaysteel.esaasfront.whs.common;
import java.io.Serializable;
import java.util.Date;
import org.apache.log4j.Logger;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import org.springframework.stereotype.Component;
import com.todaysteel.core.utils.security.SpringSecurityUtils;
import com.todaysteel.esaasfront.publiccloud.commom.security.vo.Authorization;
/**
* @author liuhaixiao
* hibernate拦截器:
* 实现创建人,创建时间自动注入;
* 修改人,修改时间自动注入;
*/
@Component
public class PropertyInterceptor extends EmptyInterceptor {
private static final Logger log = Logger.getLogger(PropertyInterceptor.class);
private static final long serialVersionUID = 1L;
@Override
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {
log.info("------Hibernate Interceptor-----onSave-----");
Authorization user = SpringSecurityUtils.getCurrentUser();
//添加数据
for (int index=0;index<propertyNames.length;index++) {
//找到名为"添加日期"的属性
if ("dadddate".equals(propertyNames[index])) {
//使用拦截器将对象的"添加日期"属性赋上值
if(state[index]==null){
state[index] = new Date();
}
continue;
} else if ("saddoperator".equals(propertyNames[index])) {//找到名为"添加人"的属性
//使用拦截器将对象的"添加人"属性赋上值
if(state[index]==null){
state[index] = user.getUsername();
}
continue;
}
}
return true;
}
@Override
public boolean onFlushDirty(Object entity, Serializable id,
Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
log.info("------Hibernate Interceptor-----onFlushDirty-----");
Authorization user = SpringSecurityUtils.getCurrentUser();
//添加数据
for (int index=0;index<propertyNames.length;index++) {
/*找到名为"修改时间"的属性*/
if ("dmodifydate".equals(propertyNames[index])) {
/*使用拦截器将对象的"修改时间"属性赋上值*/
currentState[index] = new Date();
continue;
} else if ("smodifyoperator".equals(propertyNames[index])) {/*找到名为"修改人"的属性*/
/*使用拦截器将对象的"修改人"属性赋上值*/
currentState[index] = user.getUsername();
continue;
}
}
return true;
}
}
hibernate提供了很多拦截器,在实际需要用到时才查看源码,类似于spring的AOP机制。
同理对电子商务网站需要监控日志的内容同样可以用此拦截器进行跟踪用户的行为。
当然最好是用AOP来处理跟踪用户的日志行为。
由于我是采用配置的方式来采用拦截器,所以需要在xml中进行配置。
<!-- 自定义hibernate属性拦截器 --> <bean id ="proInterceptor" class="com.todaysteel.esaasfront.whs.common.PropertyInterceptor" /> <!-- Hibernate配置 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="DynamicDataSource" /> <property name="namingStrategy"> <bean class="org.hibernate.cfg.ImprovedNamingStrategy" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> <prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache/ehcache-hibernate-local.xml</prop> </props> </property> <property name="packagesToScan" value="com.todaysteel.esaasfront,com.todaysteel.core.business" /> <property name="entityInterceptor" ref="proInterceptor"/> </bean>
我把这个拦截器的作用域是放在session级别的,所以配置在sesisonFactory上。