侧边栏壁纸
博主头像
张种恩博主等级

一个能运维的 JPG 搬运工

  • 累计撰写 703 篇文章
  • 累计创建 60 个标签
  • 累计收到 24 条评论

Hibernate(8)之延迟加载

张种恩
2017-07-28 / 0 评论 / 0 点赞 / 360 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2020-02-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

概述

延迟加载,也叫懒加载。当我们使用 session.load() 方法来加载一个对象时,此时并不会发出 SQL 语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的 id 值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出 SQL 语句,从数据库中去查询我们的对象。

类级别的延迟加载

介绍

指的是查询某个类的对象时,针对这个类的对象是否使用延迟加载。

除了修改 lazy="false" 这种方式,还可通过如下两种方式让 lazy 失效:

  1. 将持久化类以 final 修饰。
  2. 通过调用 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();
0

评论区