Hibernate回调与拦截机制 实战

下面我实现一个利用Interceptor接口实现日志数据稽核的功能,所谓日志数据稽核就是针对一些关键操作进行记录,以便作为业务跟踪的基础依据。

首先定义用于记录操作的实体:

public class AudiLog implements Serializable{

private String id;

private String user;

private String action;

private String entityName;

private String comment;

private Long logtime;

…getter/setter…

}

接下来定义Interceptor接口的实现类和用于持久化操作的AuditDAO类:

package com.lbs.apps.unemployment.subsidy.beforeinfoimport.util;

import net.sf.hibernate.Session;

import net.sf.hibernate.Interceptor;

import java.io.Serializable;

import net.sf.hibernate.type.Type;

import net.sf.hibernate.HibernateException;

import java.util.Iterator;

import java.util.Set;

import java.util.HashSet;

import com.neusoft.entity.User;

public class MyInterceptor implements Interceptor{

private Set insertset=new HashSet();

private Set updateset=new HashSet();

private Session session;

private String userID;

public void setSession(Session session){

    this.session=session

 }

 public void setUserID(String id){

   this.userID=id;

}

public boolean onLoad(Object object, Serializable serializable,

                        Object[] objectArray, String[] stringArray,

                        Type[] typeArray) {

    return false;

}

public boolean onFlushDirty(Object object, Serializable serializable,

                              Object[] objectArray, Object[] objectArray3,

                              String[] stringArray, Type[] typeArray) {

    if(object instanceof User){

      insertset.add(object);

    }

    return false;

}

public boolean onSave(Object object, Serializable serializable,

                        Object[] objectArray, String[] stringArray,

                        Type[] typeArray) {

    if(object instanceof User){

      updateset.add(object);

    }

    return false;

}

public void onDelete(Object object, Serializable serializable,

                       Object[] objectArray, String[] stringArray,

                        Type[] typeArray) {

}

public void preFlush(Iterator iterator) {

}

public void postFlush(Iterator iterator) {

try{

if(insertset.size()>0){

   AuditDAO.dolog(“insert”,userID,inserset,session.connection);

}

if(updateset.size()>0){

   AuditDAO.dolog(“update”,userID,updateset,session.connection);

}

}catch(HibernateException he){

he.printStackTrace();

}

}

public Boolean isUnsaved(Object object) {

    return null;

}

public int[] findDirty(Object object, Serializable serializable,

                         Object[] objectArray, Object[] objectArray3,

                         String[] stringArray, Type[] typeArray) {

    return null;

}

public Object instantiate(Class class0, Serializable serializable) {

   return "";

}

}

public class AuditDAO{

public static void doLog(String action,String userID,Set modifySet,Connection connection){

    Session tempsession=HibernateUtil.getSessionFactory().openSession(connection);

     try{

       Iterator it=modifyset.iterator();

       while(it.hasNext()){

         User user=(User)it.next();

         AudiLog log=new AudiLog();

         log.setUserID(userID);

         log.setAction(action);

         log.setComment(user.toString());

         log.setLogTime(new Long(Calendar.getInstance().getTime().getTime()));

         tempsession.save(log);

       }

     }catch(Exception e){

       throw new CallbackException(e);

     }finally{

       try{

         tempsesson.close();

       }catch(HibernateException he){

         throw new CallbackException(he);

       }

     }

}

}

最后看一下业务逻辑主程序:

SessionFactory sessionfactory=config.buildSessionFactory();

MyInterceptor it=new MyInterceptor();

session=sessionfactory().openSession(it);

it.setUserID(“currentUser”);

it.setSession(session);

User user=new User();

user.setName(“zx”);

Transaction tx=session.beginTransaction();

session.save(user);

tx.commit();

session.close();

以上示例代码中,在创建Session时,设置Interceptor实例对象,当执行到session.save(user)前,会触发onSave()方法,当执行tx.commit()时,会执行flush(),在执行该方法后会触发postFlush()方法,这个方法通过AuditDAO进行持久化保存业务日志,在这个类中的红色部分时有关持久化操作部分,我们并没有使用原有的Session实例,这是因为要避免Session内部状态混乱,因此我们依托当前SessionJDBC Connection创建了一个临时Session用于保存操作记录,在这个持久化操作中没有启动事务,这是因为临时Session中的JDBC Connection是与外围调用InterceptorSession共享,而事务已经在外围SessionJDBC Connection上启动。这是在拦截方法中进行持久化操作的标准方法。总之Interceptor提供了非入侵性的回调拦截机制,使我们可以方便而且优雅的实现一些持久化操作的特殊需求。

你可能感兴趣的:(.net,Hibernate,jdbc)