Hibernate的get和load區別

一、延遲加載:

     延遲加載機制是爲了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正需要數據的時候,才真正執行數據加載操作。在Hibernate中提供了對實體對象的延遲加載以及對集合的延遲加載,另外在Hibernate3中還提供了對屬性的延遲加載。下面我們就分別介紹這些種類的延遲加載的細節。

二、load和get是否是延遲加載?:

    load是true而get是false,意思就是 load採用的是延遲加載的方式 而get不是,也就是說get()採用立即加載方式,而load()採用延遲加載;,hibernate思想是 既然這個方法支持延遲加載 他就認爲這個對象一定在數據庫存在

load方法的加載過程:

      例如:Student stu = session.load(Student.class,stuid);執行此條程序,hibernate的執行過程:

      1.查詢session緩存:先查一下session緩存,看看該id對應的對象是否存在
      2.緩存中沒有這個對象 就創建個代理

      因爲延遲加載需要代理來執行 所以就創建了個代理,ok 到此爲止 這句話就執行完了,這個並沒有去數據庫交互查詢
      當你使用這個對象 比如stu.getName()或get()方法時候,此時纔會觸發sql語句
     這個時候 hibernate就去查詢二級緩存和數據庫,數據庫沒有這條數據 就拋出異常ObjectNotFoundException

四、get方法的加載過程:

    因爲hibernate規定get方法不能使用延遲加載 所以和load還是不一樣的,hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,然後在二級緩存中查找,還沒有就查數據庫,數據庫中沒有就返回null。

        例如:Student   stu = session.get(Student.class,stuid);執行此條程序,hibernate的執行過程:

        1、get方法首先查詢session緩存 (session緩存就是hibernate的一級緩存 這個概念大家應該清楚吧 )
        2、get方法如果在session緩存中找到了該id對應的對象,如果剛好該對象前面是被代理過的,如被load方法使用過,或者被其他關聯對象延遲加載過,那麼返回的還是原先的代理對象,而不是實體類對象。如果該代理對象還沒有加載實體數據(就是id以外的其他屬性數據),那麼它會查詢二級緩存或者數據庫來加載數據,但是返回的還是代理對象,只不過已經加載了實體數據。
       3、get方法如果在session緩存中找到了該id對應的對象,並且不是被延遲加載的代理對象,或者在session緩存中沒有找到該對象,則查找二級緩存,再沒有就查找數據庫,返回的對象爲實體對象,如果都沒有找到,則返回null

(這個代理實際就是空的對象並沒有去數據庫查詢得到的 我們叫代理對象,如果 去數據庫查詢了 返回到了這個對象 我們叫實體對象 就是這個對象真實存在)

我在總結性一句話這2者區別 
get方法首先查詢session緩存,沒有的話直接發送sql查詢數據庫,一定要獲取到真實的數據,否則返回null,並不適用二級緩存;反而load方法創建時首先查詢session緩存,沒有就創建代理,實際使用數據時才查詢二級緩存和數據庫,hibernate對於load方法認爲該數據在數據庫中一定存在,可以放心的使用代理來延遲加載,如果在使用過程中發現了問題,就拋異常

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章