簡體   English   中英

hibernate會話的get()和load()方法在獲取方面有什么區別?

[英]What is difference between get() and load() method of hibernate session with respect to fetching?

get()和load()方法有什么區別? 關於數據獲取方法

 public static void main(String[] args) {
    SessionFactory factory= new Configuration().configure().buildSessionFactory();
     Session session = factory.openSession();
     Transaction tx = null;
      tx = session.beginTransaction();
       System.out.println("1 st time calling load method");
        Account acc = 
               (Account)session.load(Account.class, 180); 
             System.out.println("bal"+acc.getBalance());

          System.out.println("2nd   time calling load method");
          Account  acc1=(Account)session.load(Account.class, 180); 
           System.out.println("bal"+acc1.getBalance());


        System.out.println("1 st time calling get method");
     Account acc2= (Account) session.get(Account.class, accId);

      System.out.println("bal"+acc2.getBalance());    

      System.out.println("2 st time calling get method");

     Account  acc2= (Account) session.get(Account.class, accId);

    System.out.println("bal"+acc2.getBalance());


     tx.commit();

   session.close(); 

}

我得到了以下輸出

1 st time calling load method
Hibernate: 
/* load com.abcd.Account */ select
    account0_.ACCOUNTID as ACCOUNTID1_0_,
    account0_.ACCOUNTTYPE as ACCOUNTT2_1_0_,
    account0_.CREATIONDATE as CREATION3_1_0_,
    account0_.BALANCE as BALANCE1_0_ 
from
    a.MYACCOUNT account0_ 
where
    account0_.ACCOUNTID=?
bal3000.0
2nd   time calling load method
bal3000.0
1 st time calling get method
bal3000.0
2 st time calling get method
bal3000.0

從ouput可以看出get方法沒有命中數據庫。它的行為與load()方法類似。 任何人都可以告訴我這種行為是否正確。

正如T Mishra 在此所述

  1. 默認情況下,hibernate會創建運行時代理。 它將對象作為代理加載,除非指定了獲取模式或設置為false。

  2. 那是因為一旦對象被加載到緩存中,下一個后續調用就會執行可重復讀取。

  3. 雖然此對象的狀態從持久變為分離

可以通過兩種方式檢索實體。

load() - 返回帶有標識符的代理對象。

get() - 從數據庫返回完整的對象。

有關詳細信息,請單擊此鏈接

實際上,這兩個函數都用於檢索具有不同機制的對象,

  1. session.load()

    它將始終返回“代理”(Hibernate術語)而不會訪問數據庫。 在Hibernate中,proxy是一個具有給定標識符值的對象,它的屬性尚未初始化,它看起來就像一個臨時假對象。 如果找不到行,則會拋出ObjectNotFoundException。

  2. session.get()

    它總是命中數據庫並返回真實對象,一個表示數據庫行的對象,而不是代理。 如果找不到行,則返回null。

當你調用session.load()方法時,它總會返回一個“代理”對象,什么是代理對象的含義? 代理意味着,hibernate將在內存中准備一些具有給定標識符值的虛假對象而不會訪問數據庫,例如,如果我們調用session.load(Student.class,new Integer(107)); > hibernate會在id為107的內存中創建一個偽Student對象[row],但是Student類的剩余屬性甚至都不會被初始化。 在此輸入圖像描述

得到

當您調用session.get()方法時,它將立即命中數據庫並返回原始對象。 如果該行在數據庫中不可用,則返回null。

hibernatesession.get()將從數據庫中獲取真實對象,hibernatesession.load()將返回代理而不會訪問數據庫。 有關詳細信息,請單擊此處 它解釋了get和load方法及其與示例代碼的區別。

**加載:**每當調用load()方法時,hibernate都會創建一個POJO類的代理對象,它會將id設置為代理對象,然后將代理對象返回給程序。 基於對代理對象執行的操作,hibernate將決定是否去緩存或數據庫來加載數據。 此過程稱為延遲加載。

** Get:**當我們調用get()方法時,hibernate首先進入第一級緩存,如果該對象在第一級緩存中不存在,那么它將進入數據庫並從數據庫加載對象。 如果數據庫中不存在Id,則get()方法返回null。 當調用get()方法時,不會創建代理對象,因此它被稱為早期加載。

參考: http//docs.jboss.org/hibernate/orm/4.3/javadocs/

完整示例您可以找到@ my blog: http//www.onlinetutorialspoint.com/hibernate/hibernate-session-differences-between-load-and-get.html

使用負載:

  • 如果您確定要從DB檢索的對象可用性。 否則,您將最終捕獲ObjectNotFoundException。

  • 當你有重物要加載時(因為它在你使用時懶得加載)

使用get:

  • 如果您不確定數據庫中的對象可用性。
  • 當DB中沒有可用對象時,您可以檢查是否為null。
  • 當你有輕物體要加載時(因為它急切地加載)。

以下是您需要的簡單說明: http//www.mkyong.com/hibernate/different-between-session-get-and-session-load/

或者通過查看API: http//docs.jboss.org/hibernate/orm/4.3/javadocs/

with get :返回給定命名實體的持久化實例。 持久化的,所以存儲在數據庫中的那個。

with load :將與給定標識符關聯的持久狀態讀入給定的瞬態實例。

在第一個鏈接中,您可以找到測試差異的非常有用的示例。

加載:當我們調用session.load()方法時,它不會直接命中數據庫。 如果對象不屬於db,它會創建並返回代理對象,它會拋出“ObjectNotFountException”。 並支持延遲加載。

獲取:它直接命中db中的對象,如果找不到對象則給出原始值,然后返回null。 它支持急切加載。

從上面的例子來看 - 兩個函數都不一樣。

load() - hibernate只會加載具有指定ID的對象的代理。 所有屬性都不會在高級中設置。 一旦在對象上調用getter方法,查詢就會出現問題。 因此,當您可以使用getAccount方法時,將發出select查詢,並且結果對象將在ID檢索時保存在緩存中。 所以通過get的任何后續調用都不會導致任何select語句。

get() - 將始終從填充了完整屬性的數據庫中檢索對象。 對於集合中定義的屬性,取決於延遲初始化配置。 請注意 - 同一會話中的任何后續調用都將僅從緩存中返回對象,因此不會返回任何查詢。 這就是第一次調用get方法時所發生的事情,第二次是在緩存中通過調用load檢索的對象上的acc.getBalance()來准備對象。

不要忘記get和load方法之間的性能方面

get()方法在執行時立即獲取數據,而load()方法返回代理對象,並在需要對象屬性時僅提取數據。 這樣load()方法可以獲得更好的性能,因為它支持延遲加載。 只有當我們知道數據存在時才應該使用load()方法,因為它在未找到數據時拋出異常。

您可以在教程中看到演示這種差異的示例Hibernate中get和load方法的區別

當你調用session.load()方法時,它總會返回一個proxy對象,什么是代理對象的含義? Proxy意味着,hibernate將在內存中准備一些具有給定標識符值的虛假對象而不會訪問數據庫,例如,如果我們調用。

 session.load(Student.class,new Integer(107)); 

hibernate將在id為107的內存中創建一個偽Student對象[row],但是Student類的剩余屬性甚至不會被初始化,請觀察此圖形表示...

只有當我們嘗試檢索Student對象的其他屬性時,它才會命中數據庫,我的意思是stdNamestdCountry
如果我們調用s2.getStdName()那么hibernate將命中數據庫並搜索學生ID為107的行並檢索值,如果在數據庫中找不到object [row] ,它將拋出ObjectNotFoundException


 session.get()

當您調用session.get()方法時,它將立即命中數據庫並返回原始對象。 如果該行在數據庫中不可用,則返回null


那么哪個是最好的方法,hibernate load()get() 這完全是你的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM