乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Hibernate與數(shù)據(jù)庫(kù)觸發(fā)器協(xié)同工作

       feimishiwo 2014-04-29
       
                                       Hibernate與數(shù)據(jù)庫(kù)觸發(fā)器協(xié)同工作
        數(shù)據(jù)庫(kù)觸發(fā)器是數(shù)據(jù)庫(kù)的一種監(jiān)聽(tīng)機(jī)制,這種機(jī)制會(huì)監(jiān)視數(shù)據(jù)庫(kù)中的某種特定的操作,當(dāng)這種操作發(fā)生時(shí),觸發(fā)器就會(huì)執(zhí)行,并且會(huì)完成一些特定的邏輯,在數(shù)據(jù)庫(kù)中能夠激發(fā)觸發(fā)器的操作有:insert,update,delete三種,當(dāng)這三種操作發(fā)生在一條記錄或者某個(gè)特殊字段上,如果在該記錄或者該字段上有觸發(fā)器,那么觸發(fā)器便會(huì)被激發(fā)執(zhí)行。但是當(dāng)Hibernate與觸發(fā)器協(xié)同執(zhí)行時(shí),會(huì)造成兩個(gè)問(wèn)題。
      第一:觸發(fā)器使得Session中的數(shù)據(jù)與數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致;
      第二:Sessionupdate操作會(huì)盲目觸發(fā)觸發(fā)器;
      下面我們就分別討論這兩個(gè)問(wèn)題的原因和解決辦法。
      A、觸發(fā)器使得Session中的數(shù)據(jù)與數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致:
      造成這個(gè)問(wèn)題的根本原因,是因?yàn)橛|發(fā)器對(duì)數(shù)據(jù)庫(kù)的操作對(duì)Hibernate Session是透明的,觸發(fā)器對(duì)數(shù)據(jù)庫(kù)的某些更改,無(wú)法被Session感知,因此無(wú)法被同步到緩存之中,我們看下面的代碼,假設(shè)在數(shù)庫(kù)中的user表中的registerd_time字段上設(shè)置了一個(gè)觸發(fā)器,當(dāng)有新的user對(duì)象被保存時(shí),數(shù)據(jù)庫(kù)就自動(dòng)將數(shù)據(jù)庫(kù)當(dāng)前時(shí)間之值,插入到該字段中:
      tx=session.beginTransaction();
      session.save(user);
      System.out.println(user.getRegisterdTime());
      tx.commit();
      當(dāng)執(zhí)行完save()操作后,打印注冊(cè)時(shí)間字段,這時(shí)發(fā)現(xiàn)該字段值為空。這是因?yàn)榇藭r(shí)真正的insert SQL語(yǔ)句還沒(méi)有真正執(zhí)行,所以觸發(fā)器還沒(méi)有被執(zhí)行。我們修改上面的代碼如下:
      tx=session.beginTransaction();
      session.save(user);
      session.flush();
      System.out.println(user.getRegisterdTime());
      user=session.load(User.class,”1”);
      System.out.println(user.getRegisterdTime());
      tx.commit();
      我們?cè)黾恿藦?qiáng)制清空緩存并且強(qiáng)制提交的操作,這個(gè)操作會(huì)激發(fā)insert SQL語(yǔ)句的執(zhí)行,并且激發(fā)觸發(fā)器的執(zhí)行,此時(shí)打印注冊(cè)時(shí)間發(fā)現(xiàn)已經(jīng)變成了數(shù)據(jù)庫(kù)當(dāng)前時(shí)間,但是當(dāng)再次加載剛剛被保存的user對(duì)象后打印注冊(cè)時(shí)間,發(fā)現(xiàn)還是空值,這是因?yàn)橛捎谟|發(fā)器會(huì)自動(dòng)填寫(xiě)注冊(cè)時(shí)間值,所以在構(gòu)造user對(duì)象時(shí)沒(méi)有設(shè)置該屬性值,這個(gè)屬性值被觸發(fā)器在數(shù)據(jù)庫(kù)端自動(dòng)設(shè)置,但是由于觸發(fā)器對(duì)數(shù)據(jù)庫(kù)的操作對(duì)Hibernate Session是透明的,觸發(fā)器對(duì)該字段的更改,無(wú)法被Session感知,所以在緩存中該字段仍然是null,當(dāng)加載這個(gè)對(duì)象時(shí),由于save操作此對(duì)象被置于緩存中,所以load方法從緩存中將該對(duì)象獲得,當(dāng)調(diào)用user.getRegisterdTime()時(shí)會(huì)得到緩存中的空值。那么我們?cè)鯓硬拍鼙苊獬霈F(xiàn)這個(gè)問(wèn)題呢?看下面的代碼:
      tx=session.beginTransaction();
      session.save(user);
      session.flush();
      System.out.println(user.getRegisterdTime());
      session.refresh(user);
      user=session.load(User.class,”1”);
      System.out.println(user.getRegisterdTime());
      tx.commit();
      這里我們調(diào)用了refresh方法,該方法會(huì)重新從數(shù)據(jù)庫(kù)中加載剛剛被保存的user對(duì)象到緩存中,這樣就同步了緩存與數(shù)據(jù)庫(kù)數(shù)據(jù),所以當(dāng)再次調(diào)用load方法時(shí),從緩存中獲得的數(shù)據(jù)就會(huì)同數(shù)據(jù)庫(kù)中的數(shù)據(jù)保持同步,所以再次打印注冊(cè)時(shí)間時(shí),就會(huì)打印出數(shù)據(jù)庫(kù)當(dāng)前時(shí)間。
      B、Sessionupdate操作會(huì)盲目觸發(fā)觸發(fā)器:
      如果在數(shù)據(jù)庫(kù)中定義了針對(duì)update操作的觸發(fā)器,那么必須要謹(jǐn)慎的使用SessionupdatesaveOrUpdate(),因?yàn)檫@兩個(gè)方法能夠使一個(gè)游離對(duì)象再次變成持久化對(duì)象,因?yàn)橛锌赡茉?/span>Session的緩存中,還不存在要更新對(duì)象的快照,所以就無(wú)法判斷游離對(duì)象的屬性是否與數(shù)據(jù)庫(kù)中保持一致,為了保險(xiǎn)起見(jiàn),Hibernate默認(rèn)的操作是,不管實(shí)體對(duì)象的屬性是否發(fā)生了變化,都要發(fā)起一條update SQL語(yǔ)句的執(zhí)行,來(lái)同步實(shí)體對(duì)象屬性值與數(shù)據(jù)庫(kù)字段值,即同步數(shù)據(jù)庫(kù)字段值與緩存數(shù)據(jù)屬性值。這時(shí)如果對(duì)應(yīng)的數(shù)據(jù)庫(kù)表中有update觸發(fā)器,那么就會(huì)觸發(fā)該觸發(fā)器的執(zhí)行,但是如果此時(shí)這個(gè)對(duì)象的屬性值并沒(méi)有發(fā)生改變,也就是說(shuō)實(shí)體對(duì)象的屬性值與數(shù)據(jù)庫(kù)中對(duì)應(yīng)表的對(duì)應(yīng)記錄保持一致,那么,這個(gè)觸發(fā)器的執(zhí)行就是沒(méi)有必要的,此時(shí)Sessionupdate操作就觸發(fā)了多余的觸發(fā)器。那么我們?cè)鯓硬拍鼙苊膺@個(gè)問(wèn)題呢?我們可以開(kāi)啟實(shí)體對(duì)象配置文件中<class>元素的,“select-before-update”屬性選項(xiàng),我們可以如下進(jìn)行配置:
      <class name=”com.neusoft.entity.User” table=”user” select-before-update=”true”>
       
         ……
       
      </class>
      這時(shí)當(dāng)執(zhí)行Session.update()/saveOrUpdate()操作時(shí),會(huì)首先執(zhí)行select SQL,查詢出該對(duì)象所有
      屬性值,然后與要進(jìn)行更新的實(shí)體對(duì)象屬性值進(jìn)行比較,如果都相同,那么就不會(huì)執(zhí)行update
      作,這時(shí)就不會(huì)由于執(zhí)行了沒(méi)必要的update SQL語(yǔ)句,而激發(fā)多余的update觸發(fā)器操作了。
       

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多