什么事延迟加载?
当真正需要数据时才执行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去查询!