博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate 配置详解(3)
阅读量:5236 次
发布时间:2019-06-14

本文共 3340 字,大约阅读时间需要 11 分钟。

7) hibernate.max_fetch_depth

该属性用于设置left out join单对象查询关系(one-to-one/many-to-one)中最大的关联深度。默认值为0,即默认情况不使用out-join(而使用延迟加载),建议的取值为0-3之间。

要理解max_fetch_depth属性,就必须要理解在one-to-one/many-to-one元素上的out-join属性。我们用下面的一个例子来说明:

public class Department {private Long id;private String name;private Employee manager;}public class Employee {private Long id;private Department dept;}
Employee对象中有一个dept属性代表员工所属的部门,而在Department对象中有一个manager属性代表部门的管理员,按照正常的映射:

 

那么,通过get/load方法无论是得到Department对象再得到对应的manager,或者得到Employee对象再得到对应的depthibernate默认都会采用延迟加载得到对应的manager/dept。这个就是我们说的,默认情况下,在many-to-one中,通过many方得到one方,采用延迟加载策略。但是我们也知道,使用延迟加载,会导致额外的SELECT产生,特别是在查询的时候,容易产生N+1问题,所以,我们可以使用适当的fetch策略来修改hibernate加载对象的方式。我们以下只讨论many-to-onefetch属性及策略(以Employee中的dept属性为例):

 

1,join:在一条SQL中使用LEFT OUT JOIN直接查询出many方和对应的one

 

加载策略:直接使用一条left out joinEmployee对应的Department对象查询出来,没有延迟加载:

 

select employee0_.id as id1_1_1_, employee0_.DEPT_ID as DEPT2_1_1_, department1_.id as id1_0_0_, department1_.name as name2_0_0_, department1_.manager as manager3_0_0_ from Employee employee0_ left outer join Department department1_ on employee0_.DEPT_ID=department1_.id where employee0_.id=?

 

2,select:再两条SQL中分别使用SELECT查询出many方和对应的one

 加载策略:使用延迟加载,使用另一条SELECT语句查询出Employee对应的Department对象。

可以看到,使用fetch=join就可以缓解N+1问题,减少SQL。理解到这个,就可以理解到out-join属性。在many-to-one上还有一个outer-join属性,outer-join的取值可以为auto,false,true,默认值为auto(可以想象为false),即不使用LEFT OUT JOIN,如果设置为true,就相当于fetch=join,在一条SQL中使用LEFT OUT JOIN直接查询出many方和对应的one方。当然,这还需要看fetch属性的取值,比如fetch=select,就算outer-join=true,也会使用延迟加载,因为fetch规定的是获得关联对象的方式,而outer-join只是规定是否用LEFT OUT JOIN获取关联对象,所以我简单理解为fetch的级别高于outer-join(个人理解方式)。

理解到outer-join的好处之后,问题接着就来了,我们可以看到,假如在Employee方的dept设置为outer-jointrue,那么在得到Employee的时候,就会立刻使用LEFT OUT JOIN取得对应的Department对象,那如果Department对象的manager属性的outer-join也设置为true,那么在得到Department对象时,又会立刻使用LEFT OUT JOIN关联到Employee表,如果大量的关联对象都设置了outer-join属性,那么在得到一个对象的时候,就会引起大量的表的外连接查询,导致查询效率也会非常慢,在这种情况下,就可以通过设置hibernate.max_fetch_depth来限制外链表的数量。比如:

如果没有设置hibernate.max_fetch_depth,就会使用两个LEFT OUT JOINEmployeeEmployee对应的departmentdepartment对应的manager都查询出来:

 

select employee0_.id as id1_1_2_, employee0_.DEPT_ID as DEPT2_1_2_, department1_.id as id1_0_0_, department1_.name as name2_0_0_, department1_.manager as manager3_0_0_, employee2_.id as id1_1_1_, employee2_.DEPT_ID as DEPT2_1_1_ from Employee employee0_ left outer join Department department1_ on employee0_.DEPT_ID=department1_.id left outer join Employee employee2_ on department1_.manager=employee2_.id where employee0_.id=?

 

如果设置:

hibernate.max_fetch_depth 1

那么就只会使用一条LEFT OUT JOIN只查询出Employeeemployee对应的department

 

select employee0_.id as id1_1_1_, employee0_.DEPT_ID as DEPT2_1_1_, department1_.id as id1_0_0_, department1_.name as name2_0_0_, department1_.manager as manager3_0_0_ from Employee employee0_ left outer join Department department1_ on employee0_.DEPT_ID=department1_.id where employee0_.id=?

 

同样,这个参数对fetch=join的情况也适用。

另外,如果是通过查询:

session.createQuery("FROM Employee").list();session.createCriteria(Employee.class).list();
那么,只有当使用Criteria的方式查询,fetch或者outer-join才会起作用,而使用Query对象查询,是只会查询出Employee的。这点需要非常注意。

转载于:https://www.cnblogs.com/james1207/p/3275420.html

你可能感兴趣的文章
基于反射技术汽车电子产品(ECU, SCM, 开关等)测试平台软件 (二)
查看>>
纪念日倒计时程序
查看>>
Python读取PDF文档
查看>>
leetcode-Game of Life-289
查看>>
(转)浅谈移动操作系统的跨应用通信机制
查看>>
常用的Hql语句
查看>>
可变字符串
查看>>
Postman
查看>>
事件的故事说明
查看>>
超大型 LED 显示屏
查看>>
poj 2342 Anniversary party_经典树状dp
查看>>
以后再也不写英文的文章了
查看>>
JS常用
查看>>
c# 怎么动态修改webservice的地址和端口 动态修改配置文
查看>>
usaco-5.1-theme-passed
查看>>
Android程序对不同手机屏幕分辨率自适应的总结
查看>>
分治法
查看>>
java并发值多线程同步业务场景以及解决方案
查看>>
Android开发——LinearLayout和RelativeLayout的性能对比
查看>>
URL传递中文参数,大坑一枚,Windows与Linux效果竟然不一致(两种解决方法)
查看>>