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

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

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

    Sealyu

    --- 博客已遷移至: http://www.sealyu.com/blog

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks

    get和load方式是根據id取得一個記錄

    下邊詳細說一下get和load的不同,因為有些時候為了對比也會把find加進來。

    1.從返回結果上對比:

    load方式檢索不到的話會拋出org.hibernate.ObjectNotFoundException異常

    get方法檢索不到的話會返回null

    2.從檢索執行機制上對比:

    get方法和find方法都是直接從數據庫中檢索

    而load方法的執行則比較復雜

    ■ 首先查找session的persistent Context中是否有緩存,如果有則直接返回

    ■ 如果沒有則判斷是否是lazy,如果不是直接訪問數據庫檢索,查到記錄返回,查不到拋出異常

    ■ 如果是lazy則需要建立代理對象,對象的initialized屬性為false,target屬性為null

    ■ 在訪問獲得的代理對象的屬性時,檢索數據庫,如果找到記錄則把該記錄的對象復制到代理對象的target上,并將initialized=true,如果找不到就拋出異常 。

    3.根本區別說明

    ■ 如果你使用load方法,hibernate認為該id對應的對象(數據庫記錄)在數據庫中是一定存在的,所以它可以放心的使用,它可以放心的使用代理來 延遲加載該對象。在用到對象中的其他屬性數據時才查詢數據庫,但是萬一數據庫中不存在該記錄,那沒辦法,只能拋異常。所說的load方法拋異常是指在使用 該對象的數據時,數據庫中不存在該數據時拋異常,而不是在創建這個對象時(注意:這就是由于“延遲加載”在作怪)。

    由于session中的緩存對于hibernate來說是個相當廉價的資源,所以在load時會先查一下session緩存看看該id對應的對象是否存在,不存在則創建代理。所以如果你知道該id在數據庫中一定有對應記錄存在就可以使用load方法來實現延遲加載。

    ■ 對于get方法,hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,然后在二級緩存中查找,還沒有就查數據庫,數據庫中沒有就返回null。

    對于load和get方法返回類型:雖然好多書中都這么說:“get()永遠只返回實體 類”,但實際上這是不正確的,get方法如果在 session緩存中找到了該id對應的對象,如果剛好該對象前面是被代理過的,如被load方法使用過,或者被其他關聯對象延遲加載過,那么返回的還是 原先的代理對象,而不是實體類對象,如果該代理對象還沒有加載實體數據(就是id以外的其他屬性數據),那么它會查詢二級緩存或者數據庫來加載數據,但是 返回的還是代理對象,只不過已經加載了實體數據。

    get方法首先查詢session緩存,沒有的話查詢二級緩存,最后查詢數據庫;反而load方法創建時首先查詢session緩存,沒有就創建代理,實際使用數據時才查詢二級緩存和數據庫。

    4.簡單總結

    總之對于get和load的根本區別,一句話,hibernate對于load方法認為該數據在數據庫中一定存在,可以放心的使用代理來延遲加載,如果在使用過程中發現了問題,只能拋異常;而對于get方法,hibernate一定要獲取到真實的數據,否則返回null。

    文章出處:http://www.diybl.com/course/3_program/java/javajs/2008531/118292.html

    hibernate的各種保存方式的區(save,persist,update,saveOrUpdte,merge,flush,lock)及 對象的三種狀態

    hibernate的保存

    hibernate對于對象的保存提供了太多的方法,他們之間有很多不同,這里細說一下,以便區別。

    一、預備知識

    對于hibernate,它的對象有三種狀態,transient、persistent、detached

    下邊是常見的翻譯辦法:

    transient:瞬態或者自由態

    (new DeptPo(1,”行政部”,20,”行政相關”),該po的實例和session沒有關聯,該po的實例處于transient)

    persistent:持久化狀態

    (和數據庫中記錄想影射的Po實例,它的狀態是persistent, 通過get和load等得到的對象都是persistent)

    detached:脫管狀態或者游離態

    (1)當通過get或load方法得到的po對象它們都處于persistent,但如果執 行delete(po)時(但不能執行事務),該po狀態就處于detached, (表示和session脫離關聯),因delete而變成游離態可以通過save或saveOrUpdate()變成持久態

    (2)當把session關閉時,session緩存中的persistent的po對象也變成detached

    因關閉session而變成游離態的可以通過lock、save、update變成持久態

    持久態實例可以通過調用 delete()變成脫管狀態。

    通過get()或load()方法得到的實例都是持久化狀態的。

    脫管狀態的實例可以通過調用lock()或者replicate()進行持久化。

    save()和persist()將會引發SQL的INSERT,delete()會引發SQLDELETE,

    而update()或merge()會引發SQL UPDATE。對持久化(persistent)實例的修改在刷新提交的時候會被檢測到,它也會引起SQL UPDATE。

    saveOrUpdate()或者replicate()會引發SQLINSERT或者UPDATE

    二、save 和update區別

    把這一對放在第一位的原因是因為這一對是最常用的。

    save的作用是把一個新的對象保存

    update是把一個脫管狀態的對象或自由態對象(一定要和一個記錄對應)更新到數據庫

    三、update 和saveOrUpdate區別

    這個是比較好理解的,顧名思義,saveOrUpdate基本上就是合成了save和update,而update只是update;引用hibernate reference中的一段話來解釋他們的使用場合和區別

    通常下面的場景會使用update()或saveOrUpdate():

    程序在第一個session中加載對象,接著把session關閉

    該對象被傳遞到表現層

    對象發生了一些改動

    該對象被返回到業務邏輯層最終到持久層

    程序創建第二session調用第二個session的update()方法持久這些改動

    saveOrUpdate(po)做下面的事:

    如果該po對象已經在本session中持久化了,在本session中執行saveOrUpdate不做任何事

    如果savaOrUpdate(新po)與另一個與本session關聯的po對象擁有相同的持久化標識(identifier),拋出一個異常

    org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.itfuture.www.po.Xtyhb#5]

    saveOrUpdate如果對象沒有持久化標識(identifier)屬性,對其調用save() ,否則update() 這個對象

    四、persist和save區別

    這個是最迷離的一對,表面上看起來使用哪個都行,在hibernate reference文檔中也沒有明確的區分他們.

    這里給出一個明確的區分。(可以跟進src看一下,雖然實現步驟類似,但是還是有細微的差別)

    主要內容區別:

    1,persist把一個瞬態的實例持久化,但是并"不保證"標識符(identifier主鍵對應的屬性)被立刻填入到持久化實例中,標識符的填入可能被推遲到flush的時候。

    2,save, 把一個瞬態的實例持久化標識符,及時的產生,它要返回標識符,所以它會立即執行Sql insert

    五、saveOrUpdate,merge和update區別

    比較update和merge

    update的作用上邊說了,這里說一下merge的

    如果session中存在相同持久化標識(identifier)的實例,用用戶給出的對象覆蓋session已有的持久實例

    (1)當我們使用update的時候,執行完成后,會拋出異常

    (2)但當我們使用merge的時候,把處理自由態的po對象A的屬性copy到session當中處于持久態的po的屬性中,執行完成后原來是持久狀態還是持久態,而我們提供的A還是自由態

    六、flush和update區別

    這兩個的區別好理解

    update操作的是在自由態或脫管狀態(因session的關閉而處于脫管狀態)的對象//updateSQL

    而flush是操作的在持久狀態的對象。

    默認情況下,一個持久狀態的對象的改動(包含set容器)是不需要update的,只要你更改了對象的值,等待hibernate flush就自動更新或保存到數據庫了。hibernate flush發生在以下幾種情況中:

    1, 調用某些查詢的和手動flush(),session的關閉、SessionFactory關閉結合

    get()一個對象,把對象的屬性進行改變,把資源關閉。

    2,transaction commit的時候(包含了flush)

    七、lock和update區別

    update是把一個已經更改過的脫管狀態的對象變成持久狀態

    lock是把一個沒有更改過的脫管狀態的對象變成持久狀態(針對的是因Session的關閉而處于脫管狀態的po對象(2),不能針對因delete而處于脫管狀態的po對象)

    對應更改一個記錄的內容,兩個的操作不同:

    update的操作步驟是:

    (1)屬性改動后的脫管的對象的修改->調用update

    lock的操作步驟是:

    (2)調用lock把未修改的對象從脫管狀態變成持久狀態-->更改持久狀態的對象的內容-->等待flush或者手動flush

    八、clear和evcit的區別

    clear完整的清除session緩存

    evcit(obj)把某個持久化對象從session的緩存中清空。

    posted on 2009-08-19 11:00 seal 閱讀(559) 評論(0)  編輯  收藏 所屬分類: Hibernate
    主站蜘蛛池模板: 免费人成在线观看网站视频| 免费毛片在线看片免费丝瓜视频| 在线a亚洲v天堂网2018| 亚洲一区二区三区在线观看蜜桃| 最近免费最新高清中文字幕韩国 | 亚洲精品V欧洲精品V日韩精品| 羞羞视频免费网站含羞草| 免费中文字幕在线| 一区二区免费在线观看| 亚洲国产成人精品91久久久| 一级毛片免费不卡直观看| 国产a v无码专区亚洲av| 久草免费福利在线| 亚洲一区二区影院| 无码精品A∨在线观看免费| 亚洲人片在线观看天堂无码| 成人免费无遮挡无码黄漫视频| 亚洲成熟丰满熟妇高潮XXXXX| 又大又硬又爽免费视频| 国产精品免费久久久久电影网| 久久被窝电影亚洲爽爽爽| 91精品国产免费久久国语蜜臀| 亚洲第一成年网站大全亚洲| 国产精品成人免费一区二区| 色偷偷亚洲第一综合网| 亚洲熟妇无码乱子AV电影| 无码免费一区二区三区免费播放 | 国产精品福利在线观看免费不卡 | 亚洲成a人不卡在线观看| 国产精品美女午夜爽爽爽免费| 国产精品无码亚洲精品2021| 在线亚洲精品福利网址导航| 真实国产乱子伦精品免费| 亚洲免费福利在线视频| 亚洲国产成人久久笫一页| 人妻无码一区二区三区免费| 亚洲综合中文字幕无线码| MM131亚洲国产美女久久| 四虎精品视频在线永久免费观看| 亚洲av午夜国产精品无码中文字| 亚洲区小说区图片区QVOD|