什么事延遲加載?
當真正需要數據時才執行SQL語句,其本意是減少不必要的性能開銷!
之前提到過一個延遲加載的例子:
load();結果集不能為空
當真正去打印對象屬性時,sql語句才執行!
hibernate的lazy屬性:
lazy屬性
類級別:true(默認)/false
一對多關聯級別:true(默認)/extra(加強延遲加載)/false
多對一關聯級別:proxy(默認)/no-proxy(無代理加載)/false
下面用代碼來區別他們:
類級別:
這里使用load()屬性,get()屬性在操作類級別時不具備延遲加載特性
1 /** 2 * 測試延遲加載 3 */ 4 public void get(){ 5 session=factory.openSession(); 6 session.beginTransaction(); 7 //類加載 8 Student stu=(Student)session.load(Student.class,2); 9 //測試 10 System.out.println("--輸出了--"); 11 //輸出姓名 12 System.out.println(stu.getName()); 13 session.close(); 14 } 15 16 /** 17 *--輸出了-- 18 *Hibernate: 19 * select 20 * student0_.stuno as stuno1_0_, 21 * student0_.name as name1_0_, 22 * student0_.gradeid as gradeid1_0_ 23 * from 24 * student student0_ 25 * where 26 * student0_.stuno=? 27 *小芳 28 * 29 **/
可以看到延遲加載了!
現在我修改class lazy屬性為false;
/** *<class name="Student" table="student" dynamic-update="true" *lazy="false"> **/ /**get()方法里面代碼不變**/ /** *Hibernate: * select * student0_.stuno as stuno1_0_, * student0_.name as name1_0_, * student0_.gradeid as gradeid1_0_ * from * student student0_ * where * student0_.stuno=? *--輸出了-- *小芳 * **/
一對多關聯級別:
現在我們將類級別去掉,一對多關聯獲取一遍,使用session.get()方法測試
1 /** 2 * 一對多延遲加載 3 */ 4 public void getByone2more(){ 5 session=factory.openSession(); 6 session.beginTransaction(); 7 //類加載 8 Grade grade=(Grade)session.load(Grade.class,2); 9 Set<Student> stu=grade.getStu(); 10 11 //測試 12 System.out.println("--輸出了--"); 13 //輸出集合大小 14 System.out.println(stu.size()); 15 //輸出姓名 16 for(Student st:stu){ 17 System.out.println(st.getName()); 18 19 } 20 session.close(); 21 22 23 }
默認配置下:
跟前面的一樣,先查詢年級。打印”輸出了“;
先執行了get()發起的select語句!
更改lazy 屬性為 extra:
輸出結果:
注釋掉打印學生那句:
會發現查詢總記錄時,select count(stuno),我們在將extra改為true,這時候查詢語句select stuno,name......
總結:
有的時候我們只需要知道集合中元素的個數,或者集合是否為空,并不需要知道都有哪些數據時,可以使用extra提高效率。
可見加強延遲加載采用了特定的語句查詢必要的語句
--多對一
默認的lazy屬性值為proxy;
設置為proxy時,延遲加載,同上,當查詢 id時,不會執行sql去查詢!
文章列表