一、什么是延迟加载
为了节省Hibernate加载对象的性能节销,在Hibernate中真正需要用到这个对象时,才会发出
SQL语句来抓取这个对象。这一个过程称为延迟加载。
二、延迟加载的分类
A:实体对象的延迟加载
B:一对多|多对多的延迟加载
C:多对一|一对一的延迟加载
D:属性的延迟加载
-
A:实体对象的延迟加载:使用session.get()和session.load()获取对象的区别就是是否开启延迟加载。
Hibernate只加载实体对象的ID,需要其他属性,才真正的发出SQL来加载这个对象。
Load:采用延迟加载 加载到的是一个代理对象
Get:没有采用延迟加载 加载到的是一个实体对象。
- 案例:
User user=(User)session.load(clazz, id);//直接返回的是代理对象
System.out.println(user.getId());//没有发送sql语句到数据库加载
user.getName();//创建真实的User实例,并发送sql语句到数据库中
- 注意:1.不能判断User=null;代理对象不可能为空
2.代理对象的限制:和代理关联的session对象,如果session关闭后访问代理则抛异常。session关闭之前访问数据库
-
B:一对多|多对多的延迟加载
fetch = FetchType.Lazy:表示开启延迟加载。读取班级时,不会发出读取学生的SQL语句。等真正使用学生数据时,才会发出一条SQL语句读取学生
fetch = FetchType.EAGER:取消延迟加裁。读取班级会左关联读取学生。
@OneToMany(cascade = { CascadeType.REMOVE },fetch=FetchType.EAGER)
@JoinColumn(name = "classes_id")
@OrderBy(value = " studentID desc")
public List<StudentBean> getStuList() {
return stuList;
}
-
C : 多对一|一对一的延迟加裁
默认是取消延迟加载的。
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "group_id")
private GroupBean groupBean;
- 延迟加载带来的问题: session关闭之后,再访问代理对象(延迟加载获取的是代理对象)会抛出“no session”异常。
package action; import java.util.Set; import javassist.compiler.ast.IntConst; import org.hibernate.Session; import org.hibernate.Transaction; import bean.ClassBean; import bean.StudentBean; import util.HibernateSessionUtil; public class Test { public static void main(String[] args) { ClassBean cla=Test.load(); //当Test.load()执行完毕之后,session就被关闭,这时候再访问代理对象则会抛出异常。 使用session。get就不会出现这个问题 System.out.println(cla.getClassName()); } private static ClassBean load() { ClassBean cla = null; Session session = null; Transaction tran = null; try { session = HibernateSessionUtil.getSession(); tran = session.beginTransaction(); cla = (ClassBean) session.load(ClassBean.class, new Integer(2)); //使用延迟加载,获得的是代理对象 tran.commit(); return cla; } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { HibernateSessionUtil.closeSession(); //关闭session } return null; } }
- 橙色字体处代码会出现“no session”异常。