Hibernate中的类加载
1、什么是延迟加载?
延迟加载:lazy(懒加载)。执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。
2、延迟加载的分类
(1)类级别的延迟加载
(2)关联级别的延迟加载
3、类级别延迟加载
(1)类级别的延迟加载
指的是通过load方法查询某个对象的时候,是否采用延迟。
session.load(Emp.class, 1001);
(2)类级别的延迟加载怎么配置?
类级别延迟加载,通过该类映射文件中的标签里的属性lazy进行配置为true。当然默认就是true,不配置也行。
(3)延迟加载失效情况有哪些?
- lazy默认值是true,如果设置为false,类级别延迟加载会失效。
- 如果持久化类使用final修饰,也会导致类级别延迟加载失效。
- Hibernate. initialize(obj)方法也会取消延迟加载,执行到这行代码会立马发送查询语句。
4、关联级别的延迟加载
(1)指的是在查询到某个对象的时候,查询其关联的对象的时候,是否采用延迟加载。
Dept dept= session.get(Dept.class, 10);
dept.getEmps();
// 通过部门获得员工的时候,员工对象是否采用了延迟加载,称为是关联级别的延迟。
(2)如何配置关联级别的延迟加载
关联级别延迟加载,通过该类映射文件中的或者标签里的属性lazy进行配置。
抓取策略往往会和关联级别的延迟加载一起使用,优化语句。
Hibernate中的抓取策略
1、什么是抓取策略?
通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样格式通过策略进行配置。
2、怎么配置抓取策略?
通过<set>或者<many-to-one>中的fetch, lazy属性进行设置。
fetch 和 lazy如何设置,达到优化SQL语句?
3、<set>上的fetch 和 lazy配置
fetch:抓取策略,控制SQL语句格式。
lazy:延迟加载,控制查询关联对象的时候是否采用延迟。
(1)<set>中fetch的属性值有:
- select :默认值,发送普通的select语句,查询关联对象
- join :发送一条迫切左外连接查询关联对象。
- subselect :发送一条子查询查询其关联对象。
(2)<set>中lazy的属性值有:
- true :默认值,查询关联对象的时候,采用延迟加载。
- false :查询关联对象的时候,不采用延迟加载。
- extra :及其懒惰,在代码上使用什么,它就查询什么,没有多余的。
注意:
当fetch配置join值时,lazy值失效。
因为join是迫切左外连接,一次性已经查询了关联的对象。
总共有7种搭配。常用默认或者join。
在实际开发中,一般都采用默认值。
如果有特殊的需求,可能需要配置fetch属性为join值。
4、<many-to-one>上的fetch 和 lazy配置
fetch :抓取策略,控制SQL语句格式。
lazy :延迟加载,控制查询关联对象的时候是否采用延迟。
(1)<many-to-one>中fetch的属性值有:
- select :默认值,发送普通的select语句,查询关联对象。
- join :发送一条迫切左外连接。
(2)<many-to-one>中lazy的属性值有:
- proxy :默认值,proxy具体的取值,取决于另一端的上的lazy的值。
- false :查询关联对象,不采用延迟。
- no-proxy :(不会使用)
在实际开发中,也一般都采用默认值。
如果有特殊的需求,可能需要配置fetch属性为join值。
5、批量抓取
什么是批量抓取?
查询多个对象,其关联对象一起抓取,也叫batch-size。
例如:查询多个部门,及其关联的员工信息。
一对多关系中配置batch-size:
在一的一方映射文件中,set标签上配置batch-size属性。
在多的一方映射文件中,class标签上配置batch-size属性。
属性值默认是1,需要设置其他值。
这个值设置的为x,与数据库交互的select次数为:(N / x) + 1。
并不是越大越好,假如数据量特别大,值也设置很大,一次性加载很多数据,对于内存消耗过大。
一般设置为50。具体看需求的数据量。
如果没有配置的情况下:
查询所有部门,及其关联的员工信息。
假设有5个部门,会发送5+1条select语句,效率很低。
如果在部门映射文件set标签中配置了batch-size值为3:
则会发送(5 / 3) + 1,发送3条select语句,效率提高。
测试代码:
package com.pipi.hibernate05;
import com.pipi.hibernate04.Dept;
import com.pipi.hibernate04.Emp;
import myutils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import java.util.List;
// 测试批量抓取:bitch-size
public class Test_batch_size {
public static void main(String[] args) {
Session session = HibernateUtil.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询所有部门Dept,批量查询关联的员工Emp(dept表中有5行数据)
// 在Dept.hbm.xml中的<set>标签中配置batch-size值为3,将会发送几条select语句? 3条
String hql = "from Dept";
List<Dept> depts = session.createQuery(hql).list();
for (Dept d : depts) {
System.out.println(d);
for (Emp e : d.getEmps()) {
System.out.println(e);
}
}
session.clear(); // 清空session缓存的数据,以便影响下面的测试数据
System.out.println("-----------------------------------------------------------");
// 查询所有员工Emp,批量查询关联的部门Dept(emp表中有14行数据)
// 在Emp.hbm.xml中的<class>标签中配置batch-size值为5,将会发送几条select语句? 4条
String hql2 = "from Emp";
List<Emp> emps = session.createQuery(hql2).list();
for (Emp e : emps) {
System.out.println(e);
System.out.println(e.getDept());
}
transaction.commit();
}
}
本文详细介绍了Hibernate中延迟加载的概念,包括类级别和关联级别的延迟加载,并深入探讨了抓取策略的配置方法,如fetch和lazy属性的设置,以及批量抓取的优化策略。

1万+

被折叠的 条评论
为什么被折叠?



