概述
延迟加载,也叫懒加载。当我们使用 session.load()
方法来加载一个对象时,此时并不会发出 SQL 语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的 id
值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出 SQL 语句,从数据库中去查询我们的对象。
类级别的延迟加载
介绍
指的是查询某个类的对象时,针对这个类的对象是否使用延迟加载。
除了修改 lazy="false"
这种方式,还可通过如下两种方式让 lazy
失效:
- 将持久化类以 final 修饰。
- 通过调用
Hibernate.initialize(proxy)
; 。
示例
懒加载
修改映射文件:
<!-- com/zze/bean/Class.hbm.xml -->
<class name="com.zze.bean.Class" table="class" lazy="true">
<!-- lazy 默认为 true -->
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Class clazz = session.load(Class.class, 1);
System.out.println(clazz.getClass()); // class com.zze.bean.Class_$$_jvst718_0
System.out.println(clazz); // 发出 SQL
transaction.commit();
立即加载
修改映射文件:
<!-- com/zze/bean/Class.hbm.xml -->
<class name="com.zze.bean.Class" table="class" lazy="false">
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Class clazz = session.load(Class.class, 1); // 发出 SQL
System.out.println(clazz.getClass()); // class com.zze.bean.Class
System.out.println(clazz);
transaction.commit();
关联级别的延迟加载
介绍
指的是查询到某个对象后,再查询其关联的对象是否使用延迟加载。
示例
一对多懒加载
修改映射文件:
<!-- com/zze/bean/Class.hbm.xml -->
<set name="students" cascade="save-update" lazy="true">
<!-- lazy 默认为 true -->
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Class clazz = session.get(Class.class, 1);
Set<Student> students = clazz.getStudents();
System.out.println(students); // 发出 SQL
transaction.commit();
多对一懒加载
修改映射文件:
<!-- com/zze/bean/Student.hbm.xml -->
<many-to-one name="clazz" lazy="proxy" column="cid" class="com.zze.bean.Class"/>
<!-- proxy 为默认值,表示引用关联类的加载策略。-->
<!-- com/zze/bean/Class.hbm.xml -->
<class name="com.zze.bean.Class" table="class" lazy="true">
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Student student = session.get(Student.class, 1);
Class clazz = student.getClazz();
System.out.println(clazz); // 发出 SQL
transaction.commit();
一对多即时加载
修改映射文件:
<!-- com/zze/bean/Class.hbm.xml -->
<set name="students" cascade="save-update" lazy="false">
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Class clazz = session.get(Class.class, 1);
Set<Student> students = clazz.getStudents(); // 发出 SQL
System.out.println(students);
transaction.commit();
多对一即时加载
当关联类的
lazy="false"
时,无论当前类many-to-one
标签上的lazy
如何配置,都是即时加载。
修改映射文件,以下方式二选一:
<!-- com/zze/bean/Student.hbm.xml -->
<many-to-one name="clazz" lazy="proxy" column="cid" class="com.zze.bean.Class"/>
<!-- com/zze/bean/Class.hbm.xml -->
<class name="com.zze.bean.Class" table="class" lazy="false">
或
<!-- com/zze/bean/Student.hbm.xml -->
<many-to-one name="clazz" lazy="false" column="cid" class="com.zze.bean.Class"/>
<class name="com.zze.bean.Class" table="class" lazy="true">
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
Student student = session.get(Student.class, 1);
Class clazz = student.getClazz(); // 发出 SQL
System.out.println(clazz);
transaction.commit();
评论区