一、什么是延遲加載?
延遲加載是指當應用程序想要從數據庫獲取對象時(在沒有設置lazy屬性值為false),Hibernate只是從數據庫獲取符合條件的對象的OId從而生成代理對象,并沒有加載出對象訪問該對象的屬性時才會加載出相應的值。簡答來說就是盡可能的減少查詢的數據量。簡言之,是當在真正需要數據時,才執行Sql語句進行查詢。
二、如何配置延遲加載
在Hibernate中通過.hbm配置文件中的lazy屬性來配置,并且lazy屬性出現的位置不同其作用和取值也不同。下面來詳細介紹其在不同位置的不同取值和作用。
延遲加載分類:
01.類級別的查詢策略
02.一對多和多對多關聯的查詢策略
03.多對一關聯的查詢策略
①類級別的查詢策略
類級別可選的加載策略包括立即加載和延遲加載。默認為延遲加載。如果<class>元素的lazy屬性為true。表示采用延遲加載;如果lazy屬性為false,表示采用立即加載
以Emp和Dept為例:
在Dept.hbm.xml中的<Set>元素中添加屬性 lazy="false" 表示立即加載
測試類:
@Test public void oneTest(){ Dept dept=(Dept)session.load(Dept.class, 1); //lazy true/false 類級別 System.out.println(dept.getDeptName());
load()方法在Id屬性和getClass(),不去請求數據庫,其他屬性需請求數據庫
② 一對多和多對多關聯的查詢策略
lazy屬性的另一個屬性extra 加強延遲加載
表明采用增強延遲加載策略:在<set>元素配置lazy屬性為"extra"。增強延遲加載策略與一般的延遲加載策略(lazy="true")相似。
區別:這個策略能在進一步的幫我延遲加載這個對象,也就是代理對象的初始化時機。
關鍵代碼如下:
@Test public void loadDept() { // 獲取Session對象 Session session = HibernateUtil.currentSession(); // 如果通過load方式加載Dept對象 Dept dept=(Dept)session.load(Dept.class, 12); //拿該部門下的員工的人數:也就是集合的大小 dept.getEmps().size(); // 關閉session HibernateUtil.closeSession(); }
輸出結果如下:
③ 多對一關聯的查詢策略
<many-to-one>元素用來設置多對一關聯關系。
lazy屬性 默認值為proxy
proxy:延遲加載
no-proxy:無代理延遲加載
false:立即加載
例子:
/* * 多對一延遲加載 */ @Test public void manytoTest(){ Emp emp=(Emp)session.get(Emp.class, 2); //獲取Dept對象,因為此時的配置文件lazy是proxy,所以是代理對象 Dept dept=emp.getDept(); System.out.println(dept.getDeptName()); }
輸出結果:
無代理延遲對象:
在<many-to-one>元素中配置lazy屬性為no-proxy,表示無代理延遲加載。
@Test public void loadEmp() { // 獲取Session對象 Session session = HibernateUtil.currentSession(); // 如果通過load方式加載Dept對象 Emp emp=(Emp)session.get(Emp.class, 1); //獲取Dept對象,因為此時的配置文件lazy是proxy,所以是代理對象 Dept dept=emp.getDept(); // 關閉session HibernateUtil.closeSession(); }
此程序在加載的Emp對象dept屬性為null,當程序運行到第3行的時候將觸發Hibernate執行查詢Dept表的select語句,從而加載Dept對象,由此可見,當lazy屬性為proxy時,可以延長延遲加載Dept代理對象的時間,而lazy屬性為no-proxy時,則可以避免使用由Hibernate提供的Dept代理類實例,是Hibernate對程序提供更加透明的持久化服務。
文章列表