侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 747 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

Hibernate(8)之延迟加载

zze
zze
2017-07-28 / 0 评论 / 0 点赞 / 659 阅读 / 4892 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

概述

延迟加载,也叫懒加载。当我们使用 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

评论区