<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 431,  comments - 344,  trackbacks - 0
     

    在某些情況下,我們需要對(duì)實(shí)體的CURD操作進(jìn)行捕獲并執(zhí)行一些操作,這可以通過(guò)數(shù)據(jù)庫(kù)觸發(fā)器來(lái)實(shí)現(xiàn),但是正如我們上一節(jié)中所分析的,由于觸發(fā)器的執(zhí)行對(duì)Hibernate Session是透明的,因此會(huì)帶來(lái)很多問(wèn)題(參見(jiàn)上一節(jié))。為此Hibernate提供了一些專門用于捕獲監(jiān)聽(tīng)實(shí)體CURD操作的接口,通過(guò)這些接口可以實(shí)現(xiàn)類似觸發(fā)器的功能,能夠在實(shí)體發(fā)生CURD操作時(shí)捕獲事件,并且執(zhí)行相應(yīng)的動(dòng)作邏輯。在Hibernate中這些接口是:Lifecycle,Validatable,Interceptor,下面我們就分別講解怎樣通過(guò)這些接口,實(shí)現(xiàn)回調(diào)攔截的技術(shù)細(xì)節(jié)。

    ALifecycleValidatable

     HibernateLifecycle接口定義如下:

    public interface Lifecycle{

     /**

       在實(shí)體對(duì)象執(zhí)行save/insert操作之前觸發(fā)

     **/

     public boolean onSave(Session session) throws CallbackException;

     /**

       session.update()執(zhí)行之前觸發(fā)

     **/

     public boolean onUpdate(Session session) throws CallbackException;

     /**

     在實(shí)體對(duì)象執(zhí)行delete操作之前觸發(fā)

    **/

    public boolean onDelete(Session session) throws CallbackException;

    /**

     在實(shí)體對(duì)象加載之后觸發(fā)

    **/

    public void onLoad(Session session) throws CallbackException;

    }

    實(shí)體對(duì)象可以實(shí)現(xiàn)Lifecycle接口,來(lái)獲得在持久化階段捕獲CURD事件,并執(zhí)行相應(yīng)動(dòng)作的能如下所示:

    public class User implements Serializable,Lifecycle{

     public boolean onSave(Session s) throws CallbackException{

    ……

    return false;

    ……

     }

     public boolean onUpdate(Session s) throws CallbackException{

    ……

    return true;

    ……

     }

     public boolean onDelete(Session s) throws CallbackException{

    ……

    return false;

    ……

     }

     public boolean onLoad(Session s) throws CallbackException{

    ……

     }

    }

    對(duì)于onSave,onUpdate,onDelete方法,如果返回true則意味著需要終止執(zhí)行對(duì)應(yīng)的操作過(guò)程。如果在運(yùn)行時(shí)拋出CallbackException,對(duì)應(yīng)的操作也會(huì)被終止。

    注意在接口中對(duì)應(yīng)的方法中,不要去通過(guò)方法的Session參數(shù)執(zhí)行持久化操作,在這些方法中Session無(wú)法正常使用,如果必須要執(zhí)行一些持久化操作,那么需要進(jìn)行特殊的處理,我們將在Interceptor部分詳細(xì)講解。

    Hibernate中還定義了Validatable接口,該接口定義如下:

    public interface Validatable{

     public void validate() throws ValidationFailure;

    }

    Validatable接口是用來(lái)實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證的,實(shí)體類實(shí)現(xiàn)Validatable接口,并在接口的validate方法中實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證邏輯,以保證數(shù)據(jù)輸入的合法性。validate方法將會(huì)在實(shí)體對(duì)象持久化前得到調(diào)用進(jìn)行數(shù)據(jù)驗(yàn)證,與Lifecycle接口中的方法不同,Validatable.validate()方法在實(shí)體生命周期中可能被多次調(diào)用,因此此方法應(yīng)該僅限于數(shù)據(jù)合法性的驗(yàn)證,而不應(yīng)該實(shí)現(xiàn)業(yè)務(wù)邏輯的驗(yàn)證。

    BInterceptor:

    以上是Hibernate提供的Lifecycle接口和Validatable接口,以及使用方法,這兩個(gè)方法定義了一種自然的回調(diào)機(jī)制,但是如我們所見(jiàn),如果想實(shí)現(xiàn)對(duì)實(shí)體的回調(diào)攔截,那么相應(yīng)的實(shí)體對(duì)象必須實(shí)現(xiàn)這兩個(gè)Hibernate原生接口,這就使代碼的可移植性大大下降,因?yàn)榇藭r(shí)實(shí)體類已經(jīng)不再是一個(gè)POJO了,Hibernate的那些天才的設(shè)計(jì)者們也已經(jīng)意識(shí)到了這個(gè)問(wèn)題,所以又提供了Interceptor接口,為持久化事件的捕獲和處理提供了一個(gè)非入侵性的解決方案,Interceptor接口通過(guò)設(shè)置注入來(lái)實(shí)現(xiàn)持久化事件的捕獲和處理,這是典型的IOC(控制反轉(zhuǎn))設(shè)計(jì)思想。下面我們就講解Interceptor接口的技術(shù)細(xì)節(jié)和使用方法。

    Hibernate中的Interceptor接口定義如下:

    public interface Interceptor{

     //對(duì)象初始化之前調(diào)用,這時(shí)實(shí)體對(duì)象剛剛被創(chuàng)建,各個(gè)屬性還都為null,如果在這個(gè)方法中修改了實(shí)體對(duì)象的數(shù)據(jù),那么返回true,否則返回null.

     public boolean onLoad(Object entity,Serializable id,Object[] state,

    String[] propertyNames,Type[] types) throws CallbackException;

          //Session.flush()在進(jìn)行臟數(shù)據(jù)檢查時(shí),如果發(fā)現(xiàn)實(shí)體對(duì)象數(shù)據(jù)已臟,就調(diào)用此方法

     public boolean onFlushDirty(Object entity,Serializable id,Object[] state,

    String[] propertyNames,Type[] types) throws CallbackException;

     //實(shí)體對(duì)象被保存前調(diào)用,如果在這個(gè)方法中修改了實(shí)體對(duì)象的數(shù)據(jù),那么返回true,否則返回null.

     public boolean onSave(Object entity,Serializable id,Object[] state,

    String[] propertyNames,Type[] types) throws CallbackException;

         //通過(guò)Session刪除一個(gè)實(shí)體對(duì)象前調(diào)用

     public boolean onDelete(Object entity,Serializable id,Object[] state,

    String[] propertyNames,Type[] types) throws CallbackException;

         //Session執(zhí)行flush()之前調(diào)用

    public boolean preFlush(Iterator entities) throws CallbackException;

         //Session執(zhí)行flush()之后,所有的SQL語(yǔ)句都執(zhí)行完畢后調(diào)用

    public boolean postFlush(Iterator entities) throws CallbackException;

         //當(dāng)執(zhí)行saveOrUpdate方法時(shí)調(diào)用,判斷實(shí)體對(duì)象是否已經(jīng)保存

         public Boolean isUnsaved(Object entity);

         //執(zhí)行Session.flush()方法時(shí),調(diào)用此方法判斷該對(duì)象是否為臟對(duì)象,這提供了臟數(shù)據(jù)檢查的另一個(gè)回調(diào)攔截機(jī)制

    public int[] findDirty(Object entity,Serializable id,Object[] state,

    String[] propertyNames,Type[] types) throws CallbackException;

         //當(dāng)Session構(gòu)造實(shí)體類實(shí)例前調(diào)用,如果返回null,Hibernate會(huì)按照默認(rèn)方式構(gòu)造實(shí)體類對(duì)象實(shí)例

    public Object findDirty(Class clazz,Serializable id) throws CallbackException;

    }

    Intercepter不需要實(shí)體對(duì)象來(lái)實(shí)現(xiàn),而是通過(guò)開(kāi)發(fā)人員定義一個(gè)實(shí)現(xiàn)Interceptor接口的類,然后在創(chuàng)建Hibernate Session時(shí),通過(guò)將Interceptor對(duì)象設(shè)置進(jìn)所創(chuàng)建的Session,這樣通過(guò)這個(gè)Session來(lái)操作的實(shí)體對(duì)象,就都會(huì)具有對(duì)持久化動(dòng)作的回調(diào)攔截能力。在HibernateInterceptor對(duì)象共有兩種用法,如下所述:

    1                SessionFactory.openSession(Interceptor):為每個(gè)Session實(shí)例分配一個(gè)攔截Interceptor,這個(gè)攔截接口對(duì)象,存放在Session范圍內(nèi),為每個(gè)Session實(shí)例所專用。

    2                Configuration.setInterceptor(Interceptor):SessionFactory實(shí)例分配一個(gè)Interceptor實(shí)例,這個(gè)Interceptor實(shí)例存放在SessionFactory范圍內(nèi),被每個(gè)Session實(shí)例所共享。

    AInterceptor的典型應(yīng)用:

    下面我實(shí)現(xiàn)一個(gè)利用Interceptor接口實(shí)現(xiàn)日志數(shù)據(jù)稽核的功能,所謂日志數(shù)據(jù)稽核就是針對(duì)一些關(guān)鍵操作進(jìn)行記錄,以便作為業(yè)務(wù)跟蹤的基礎(chǔ)依據(jù)。

    首先定義用于記錄操作的實(shí)體:

    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…

    }

    接下來(lái)定義Interceptor接口的實(shí)現(xiàn)類和用于持久化操作的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);

           }

         }

     }

    }

    最后看一下業(yè)務(wù)邏輯主程序:

    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();

    以上示例代碼中,在創(chuàng)建Session時(shí),設(shè)置Interceptor實(shí)例對(duì)象,當(dāng)執(zhí)行到session.save(user)前,會(huì)觸發(fā)onSave()方法,當(dāng)執(zhí)行tx.commit()時(shí),會(huì)執(zhí)行flush(),在執(zhí)行該方法后會(huì)觸發(fā)postFlush()方法,這個(gè)方法通過(guò)AuditDAO進(jìn)行持久化保存業(yè)務(wù)日志,在這個(gè)類中的紅色部分時(shí)有關(guān)持久化操作部分,我們并沒(méi)有使用原有的Session實(shí)例,這是因?yàn)橐苊?/span>Session內(nèi)部狀態(tài)混亂,因此我們依托當(dāng)前SessionJDBC Connection創(chuàng)建了一個(gè)臨時(shí)Session用于保存操作記錄,在這個(gè)持久化操作中沒(méi)有啟動(dòng)事務(wù),這是因?yàn)榕R時(shí)Session中的JDBC Connection是與外圍調(diào)用InterceptorSession共享,而事務(wù)已經(jīng)在外圍SessionJDBC Connection上啟動(dòng)。這是在攔截方法中進(jìn)行持久化操作的標(biāo)準(zhǔn)方法。總之Interceptor提供了非入侵性的回調(diào)攔截機(jī)制,使我們可以方便而且優(yōu)雅的實(shí)現(xiàn)一些持久化操作的特殊需求。
    posted on 2009-06-11 16:49 周銳 閱讀(525) 評(píng)論(0)  編輯  收藏 所屬分類: Hibernate
    主站蜘蛛池模板: 四虎在线视频免费观看| 国产精品成人免费福利| 免费A级毛片无码视频| 99久久99这里只有免费费精品| 97免费人妻无码视频| 韩国日本好看电影免费看| 亚洲综合国产精品第一页| 国产精品亚洲片在线观看不卡| 亚洲色图黄色小说| 亚洲gay片在线gv网站| 一级成人生活片免费看| 日韩在线不卡免费视频一区| 成人免费看黄20分钟| 国产成人高清亚洲| 亚洲最大黄色网址| 黄床大片30分钟免费看| 免费一区二区无码东京热| 免费国产作爱视频网站| 亚洲精品网站在线观看不卡无广告 | 一级A毛片免费观看久久精品 | 最近2022中文字幕免费视频| 成全高清视频免费观看| 国产a v无码专区亚洲av| 亚洲春黄在线观看| jizz18免费视频| 四虎永久在线观看免费网站网址 | 国产成人精品亚洲日本在线 | 99在线视频免费观看视频| 亚洲免费日韩无码系列| 亚洲另类精品xxxx人妖| 一级毛片免费观看不收费| 在线视频免费观看爽爽爽| 亚洲国产成人久久一区久久| 亚洲欧洲精品久久| 本道天堂成在人线av无码免费| 免费h片在线观看网址最新| 亚洲午夜无码AV毛片久久| 亚洲中文字幕无码一去台湾 | 久久激情亚洲精品无码?V | 亚洲电影一区二区| 色噜噜狠狠色综合免费视频|