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

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

    • 分享

      Hibernate 數(shù)據(jù)的保存,更新和刪除

       feimishiwo 2014-04-29

       

      數(shù)據(jù)的保存,更新和刪除:
         1Session.save()方法:
      Session.save()方法用于實體對象的持久化保存,也就是說當(dāng)執(zhí)行session.save()方法時會生成對應(yīng)的insert SQL語句,完成數(shù)據(jù)的保存。如下面的代碼:
      User user=new User();
      user.setName(“zx”);
      Transaction tx=session.beginTransaction();
      session.save(user);
      tx.commit();
      當(dāng)執(zhí)行到session.save()方法時,Hibernate并不會馬上生成insert SQL語句來進(jìn)行數(shù)據(jù)的保存,而是當(dāng)稍后清理session的緩存時才有可能執(zhí)行insert SQL語句,那么session.save()方法到底會執(zhí)行哪些步驟呢?請看進(jìn)行了如下總結(jié):
      一、           session的內(nèi)部緩存中尋找保存對象,如果找到了,則認(rèn)為此數(shù)據(jù)已經(jīng)保存(曾經(jīng)執(zhí)行過insert操作),實體對象已經(jīng)處于persistent狀態(tài),直接返回。此時即使數(shù)據(jù)相比之前的狀態(tài)發(fā)生了變化,也將在事務(wù)提交時由臟數(shù)據(jù)檢查來判定是否需要執(zhí)行update操作。
      二、           如果實體對象實現(xiàn)了lifecycle接口,那么將執(zhí)行待保存對象的onSave()方法。
      三、           如果實體對象實現(xiàn)了Validatable接口,那么將會執(zhí)行相應(yīng)的validate()方法。
      四、           如果存在攔截器對象,那么將會執(zhí)行Interceptor.onSave()方法。
      五、           構(gòu)造insert SQL語句完成數(shù)據(jù)保存。
      六、           數(shù)據(jù)保存成功后,設(shè)定實體對象的id為插入記錄的id。
      七、           將保存后的實體對象納入Hibernate的內(nèi)部緩存(一級緩存)。注意Hibernate不會把保存后的實體對象納入二級緩存,因為剛剛保存過的實體對象很可能在之后被修改,緩存的頻繁更新以及帶來的同步問題代價,超出了緩存該對象所帶來的收益。
      八、           最后如果該對象有關(guān)聯(lián)對象,那么將會遞歸處理該級聯(lián)對象。
       
      1、      Session.update()方法:
        前面我在實體對象狀態(tài)轉(zhuǎn)化部分曾經(jīng)講過,session.update()方法能夠?qū)⒁粋€處于游離狀態(tài)的對象,重新納入Hibernate的內(nèi)部緩存,變成持久化對象。如下面的代碼:
      Configuration cfg = new Configuration();
      SessionFactory sf=cfg. configure().buildSessionFactory();
      Customer customer=new Customer(“zx”,27,images);//customer對象處于自由狀態(tài)
      Session session=sf.openSession();
       
      Transaction tx=session.beginTransaction();
      session.save(customer);//保存后customer對象處于持久化狀態(tài)
      session.flush();//清空緩存后customer對象處于游離狀態(tài)
      tx.commit();
      session.close();
       
      Session session2=sf.openSession();
      Transaction tx2=session2.beginTransaction();
      session2.update(customer);//通過調(diào)用update()方法將游離狀態(tài)的customer對象,再次轉(zhuǎn)化成持久化狀態(tài)
      session2.delete(customer);//調(diào)用delete()方法后,當(dāng)清空緩存時,會將customer對象移出緩存,同時會在數(shù)據(jù)庫中生成delete事務(wù),來刪除customer對象對應(yīng)的數(shù)據(jù)記錄
      tx.commit();
      session.close();
      那么這個方法到底執(zhí)行了哪些步驟呢?它會按照下面的步驟進(jìn)行操作:
      一、           首先會在緩存中尋找需要更新的實體對象,如果找到就立刻返回,從這里我們可以看出如果對一個已經(jīng)處于persistent的實體對象執(zhí)行update()方法,將不會產(chǎn)生任何作用。
      二、           然后當(dāng)提交事務(wù)進(jìn)行緩存清理時,將會通過臟數(shù)據(jù)檢查,確定變化的屬性,然后生成update SQL語句完成數(shù)據(jù)的更新。
      這里有一個問題我們要強(qiáng)調(diào)一下,那就是只要通過update()方法將一個游離對象與session相關(guān)聯(lián),那么不論這個游離的實體對象的屬性是否發(fā)生改變,都會執(zhí)行update SQL語句。如下面的代碼:
       
      Transaction tx=session.beginTransaction();
      session.update(customer);
      tx.commit();
      session.close();
      在這段代碼中并沒有修改customer對象的任何屬性值,但是也會執(zhí)行一個update SQL語句,如果你希望在沒有改變實體對象屬性值的情況下不去執(zhí)行update SQL語句,那么你要開啟實體對象<class>元素的”select-before-update”屬性,將其設(shè)置為”true”,這個屬性默認(rèn)為”false”。如下進(jìn)行配置:
      <class name=”com.neusoft.entity.Customer” table=”customer” select-before-update=”true”>
      如果啟用了這個屬性配置,那么在清理session緩存之前,會首先執(zhí)行類似如下的一條SQL語句:
      Select * from customer where id=’1’;
      查詢處所有的customer實體在數(shù)據(jù)庫中對應(yīng)的屬性值,然后逐條與緩存中屬性值進(jìn)行比較,如果發(fā)生了改變,那么將會生成update操作進(jìn)行數(shù)據(jù)更新,如果沒有發(fā)生改變那么將不會進(jìn)行update操作。要跟據(jù)實際需求情況來決定是否開啟這個選項,如果實體對象的屬性不會經(jīng)常發(fā)生改變,那么就應(yīng)該開啟這個選項,以免執(zhí)行多余的update操作。如果實體對象的屬性會經(jīng)常發(fā)生改變,那么就沒必要開啟這個選項,以免在執(zhí)行update操作前再執(zhí)行多余的select語句。
       
      注:(1)、當(dāng)執(zhí)行對一個游離實體對象執(zhí)行session.update()操作時,如果在數(shù)據(jù)庫中不存在這個實體對應(yīng)的紀(jì)錄,那么這個操作將會拋出異常。
         2)、當(dāng)執(zhí)行session.update()方法將一個游離對象與session關(guān)聯(lián)時,如果此時在緩存中已經(jīng)存在了與該實體對象具有相同OID的持久化對象,那么這個方法會拋出異常。如下面代碼:
      Customer customer1=new Customer(“1”,“zx”,27,images);
      Session session1=sf.openSession();
      Transaction tx=session1.beginTransaction();
      session.save(customer1);
      session.flush();
      tx.commit();
      session1.close();
       
      Session session2=sf.openSession();
      Transaction tx2=session2.beginTransaction();
      Customer othercustomer=(Customer)session2.load(Customer.class,”1”);
      session2.update(customer1)
      tx2.commit();
      session2.close();
      當(dāng)再次將游離對象customer1session2關(guān)聯(lián)時,此時因為load()操作,在緩存已經(jīng)加載了一個和customer1具有相同OIDothercustomer對象,此時由于Hibernate緩存的對象緩存機(jī)制不允許把OID相同的對象緩存,所以會拋出異常。
      2、      Session.saveOrUpdate():
      這個方法包含了save()方法和update()方法的特點,如果傳入該方法的是一個游離對象,那么這個方法就會執(zhí)行update操作,如果傳入該方法的是一個臨時對象,那么這個方法就會執(zhí)行insert操作。這個方法幕后的工作原理如下:
      a)        首先在緩存尋找,如果找到待保存的操作就直接返回。
      b)        如果實體實現(xiàn)了攔截方法,那么就執(zhí)行isUnsaved()方法,判斷實體對象狀態(tài)。
      c)        如果實體處于臨時狀態(tài)就執(zhí)行save(),如果實體處于游離狀態(tài)那么就執(zhí)行update()。
      這里存在一個問題,那就是Hibernate是怎樣判斷一個實體是處于游離態(tài)還是臨時狀態(tài)的?如果實體滿足下面的一個條件,就認(rèn)為這個實體處于臨時狀態(tài)。
      .Java對象的OID值為null。
      .如果Java對象具有version屬性(將在并發(fā)加鎖部分講解)且為null。
      .如果實體的<id>設(shè)置了屬性unsaved-value,而且OID值與unsaved-value值相等。
      .如果實體的version屬性設(shè)置了unsaved-value,并且version屬性的值與unsaved-value值相等。
      .如果實體實現(xiàn)了Interceptor,而且Interceptor.isUnsaved()方法返回true。
      滿足這些條件中的一個,這個實體就被認(rèn)為是臨時對象。
      3、      Session.delete():
      delete()方法用于從數(shù)據(jù)庫中刪除一個或一批實體所對應(yīng)的數(shù)據(jù),如果傳入的對象是持久化對象,么當(dāng)清理緩存時,就會執(zhí)行delete操作。如果傳入的是游離對象,那么首先會使該對象與session相關(guān)聯(lián),然后當(dāng)清理緩存時,再執(zhí)行delete操作??慈缦麓a:
      Session session=sessionFactory().openSession();
      Transaction tx=session.beginTransaction();
      Customer customer=(Customer)session.load(Customer.class,”1”);
      session.delete(customer);//計劃執(zhí)行一條delete語句
      tx.commit();//清理緩存,執(zhí)行一條delete語句
      session.close();//關(guān)閉session,這時將會把customer對象從緩存中刪除。
      如果上面的代碼中的customer對象是一個游離對象,那么當(dāng)執(zhí)行session.delete()方法時,會首先將游離的customer對象與session相關(guān)聯(lián),然后再清理緩存時,再執(zhí)行delete操作。如果你想一次刪除多條數(shù)據(jù),那么可以采用一個重載的delete()方法:delete(“from Customer c where c.id>’8’ ”);這個方法可以刪除符合條件的所有數(shù)據(jù)。

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多