Hibernate延遲加載

小編:管理員 437閱讀 2022.09.14

前言:

上一篇文章我們學習了Hibernate的多表關聯關系,這里就涉及到一個很實用的概念:延遲加載或者也叫惰性加載,懶加載。使用延遲加載可以提高程序的運行效率。Java程序與數據庫交互的頻次越低,程序運行效率越高,所以我們應該盡量減少Java程序與數據庫的交互次數,Hibernate延遲加載就很好的做到了這一點。

通過一個具體的業務場景來理解延遲加載:

客戶(Customer)和訂單(Orders),當我們查詢Customer對象時,因為有級聯關系,所以會將對應的Orders對象一并查詢出來,這樣就需要發送兩條SQL語句,分別查詢customer表和orders表中的數據。延遲加載的思路是:當我們查詢Customer的時候,如果沒有調用orders,則只發送了一條SQL語句查詢customer;如果需要調用orders,則發送兩條SQL語句查詢customer和orders。所以延遲加載可以看做是一種優化機制,根據具體的代碼,自動選擇發送的SQL語句條數。

代碼:

理解了延遲加載的概念,接下來就是如何使用了。

延遲加載使用起來很簡單,直接在實體關系映射文件中進行配置即可。

一對多:

1.查詢Customer,對orders進行延遲加載設置,在customer.hbm.xml進行設置,延遲加載默認為開啟狀態。


     
     
     
復制

所以查詢Customer,如果不調用orders,則會看到只發送一條SQL。

當調用orders的時候,發送兩條SQL。

現在將延遲加載關閉,customer.hbm.xml中將set標簽的lazy屬性改為false。


      
      
      
復制

現在繼續查詢Customer,可以看到,即使沒有調用orders屬性,也同樣發送了兩條SQL,即延遲加載已經關閉,立即加載orders對象。

lazy屬性除了可以設置true和false,還可設置extra,extra是比true更加懶惰的一種加載方式,或者說更加智能的一種加載方式,通過一個例子來理解兩者的區別:

查詢出Customer對象,然后需要打印該對象對應的orders集合的長度,使用lazy="true"。

會看到查詢了兩次SQL,第二次SQL首先將orders表中的記錄查詢出來,然后將這些記錄映射成對象,創建Set集合對象,將oreders對象放入集合對象中,然后返回集合對象的長度,這是它的流程。

若將設置改為lazy="extra",會看到這樣的SQL語句。


      
      
      
復制

同樣是兩次SQL語句,第一次SQL沒有區別。

此時第二次SQL語句是使用聚會函數來統計orders的總記錄數,最終將結果2返回,與上面的操作接收到的結果是一樣的。

但是很顯然,這種方式更加高效,因為SQL直接統計了記錄數然后返回,省去了查出記錄--封裝對象--放入集合--返回集合長度這一復雜的流程。

所以,通過這個例子我們可以看出,extra是更高效的一種加載方式,不到需要加載數據庫具體數值的時候,是不會直接查詢記錄的。

這是通過Customer來設置orders的延遲加載,同理,我們也可以通過Orders來設置customer的延遲加載。

在orders.hbm.xml中進行設置。默認值為false,即關閉延遲加載。

復制

所以,查詢Orders時,會發送兩次SQL語句分別查詢Orders以及級聯的Customer。

現在將lazy的值進行修改,這個時候會發現,lazy的值不能改為true,可供我們選擇的只有false proxy no-proxy。

其實這里的proxy和no-proxy是將開啟延遲加載又進行了細分:

設置為no-proxy,當調用方法需要訪問customer的成員變量時,發送SQL語句查詢Customer,否則不發送。

設置為proxy,無論調用的方式是否需要訪問customer的成員變量,都會發送SQL查詢Customer。

這是兩者的區別,但是在使用時,no-proxy編譯時需要進行字節碼增強操作,否則作用和proxy是一樣的。

多對多:

查詢Classes,加載對應的Student,默認延遲加載是開啟的,在classes.hbm.xml中進行設置。


    
    
    
復制

所以查詢Classes,從控制臺看到只發送了一次SQL語句。

當調用Classes的students屬性時,發送兩次SQL。

現在將lazy改為false。


      
      
      
復制

可以看到沒有調用students屬性,依然發送了兩次SQL。

同理,lazy的第三個可選值extra與一對多關系是一樣的,是比true更加懶惰的加載方式。

獲取Student,調用classes也是同樣的配置,在student.hbm.xml中進行配置即可。

總結:

Hibernate延遲加載的配置有很多種方式,都是通過給標簽設置lazy屬性完來完成,并且不同的標簽lazy屬性的值是不一樣的,重點還是理清楚實體類之間的關聯關系,才可以通過設置lazy屬性實現優化代碼效率的目的。

關聯標簽:
亚洲国产欧美图片,亚洲aⅴ在线av,日韩亚洲综合图片视频,日本av精品在线中文