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属性代表部门的管理员,按照正常的映射:

<class name="Department">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<many-to-one name="manager" class="Employee"/>
</class> <class name="Employee">
<id name="id">
<generator class="native" />
</id>
<many-to-one name="dept" column="DEPT_ID"/>
</class>

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

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

加载策略:直接使用一条left out join把Employee对应的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-join为true,那么在得到Employee的时候,就会立刻使用LEFT OUT JOIN取得对应的Department对象,那如果Department对象的manager属性的outer-join也设置为true,那么在得到Department对象时,又会立刻使用LEFT OUT JOIN关联到Employee表,如果大量的关联对象都设置了outer-join属性,那么在得到一个对象的时候,就会引起大量的表的外连接查询,导致查询效率也会非常慢,在这种情况下,就可以通过设置hibernate.max_fetch_depth来限制外链表的数量。比如:

<class name="Department">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<many-to-one name="manager" class="Employee" outer-join="true"/>
</class> <class name="Employee">
<id name="id">
<generator class="native" />
</id>
<many-to-one name="dept" column="DEPT_ID" outer-join="true"/>
</class>

如果没有设置hibernate.max_fetch_depth,就会使用两个LEFT OUT JOIN把Employee,Employee对应的department,department对应的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只查询出Employee和employee对应的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的。这点需要非常注意。

Hibernate 配置详解(3)的更多相关文章

  1. Hibernate 配置详解(9)

    hibernate.cache.use_structured_entries Hibernate文档上介绍,该属性是用于把对象以一种更易读的方式放到二级缓存中,这样,在对二级缓存进行监控的时候就更容易 ...

  2. Hibernate 配置详解(2)

    6) hibernate.session_factory_name: 配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中.一般名字格式 ...

  3. Hibernate 配置详解(5)

    9) hibernate.batch_fetch_style: 该配置是hibernate4.2.0新添加的,使用这个设置可以配置hibernate在做batch-fetch的时候,生成SQL的策略. ...

  4. Hibernate 配置详解(8)

    hibernate.generate_statistics 这个配置大家应该都很熟悉,用于开启Hibernate统计信息,便于对Hibernate相关性能调试提供数据依据.在开发过程当中,可以把这个选 ...

  5. Hibernate 配置详解(12) 补充

    hibernate.hbm2ddl.import_files_sql_extractor 这个配置项用于补充这篇文章: http://blog.csdn.net/stefwu/article/deta ...

  6. Hibernate 配置详解(12) 其实我也不想用这么土的名字

    hibernate.hbm2ddl.import_files 这个配置用于在hibernate根据映射文件执行DDL之前,如果我们自己设置了要事先运行的SQL文件,hibernate就会先执行这些SQ ...

  7. Hibernate 配置详解(7)

    hibernate.order_updates: Hibernate文档中提到,该配置用于在刷新一级缓存,提交UPDATE的时候,按照每类对象的主键顺序排序后再提交,可以在高并发情况下减少事务死锁的可 ...

  8. Hibernate 配置详解(11)

    hibernate.session_factory_name_is_jndi 配置hibernate.cfg.xml中SessionFactory的name属性是否作为JNDI名称绑定.默认是true ...

  9. hibernate二级缓存ehcache hibernate配置详解

    <!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...

  10. Hibernate配置详解

    <!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> <?xml version='1.0' ...

随机推荐

  1. Java基础知识强化之集合框架笔记40:Set集合之HashSet存储自定义对象并遍历

    1. HashSet存储自定义对象并遍历 2. 代码示例: (1)Student类,如下: package cn.itcast_02; /** * @author Administrator * */ ...

  2. iOS UIKit:viewController之Segues (4)

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  3. HTML简单介绍及常见元素

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 9.27 noip模拟试题

    工资 (money/money.in/money.out) 时限1000ms 内存256MB 聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi.有m个结算工钱的时间,聪哥可 ...

  5. uploadify插件实现多个图片上传并预览

    使用uploadify插件可方便实现图片上传功能.兼容ie6.ie7. 上传成功之后使用插件的回调函数读取json数据,根据url实现图片预览. 效果图: 点击浏览文件上传图片,图片依次在右侧显示预览 ...

  6. 最新xgboost python32位下安装xgboost

    网上很多windows python下安装xgboost都是很简单的几步无非是visual studio2013以上版本编译,安装.但现在最新的xgboost已经移除了c++工程文件,找到旧版本的也多 ...

  7. String、StringBuffer、StringBuilder

    也说String. String:不可变字符序列. StringBuffer:线程安全的可变字符序列. StringBuilder:StringBuffer的非线程安全实现,JDK1.5+. publ ...

  8. Vijos1865 NOI2014 魔法森林 LCT维护生成树

    基本思路: 首先按照weightA升序排序,然后依次在图中加边,并维护起点到终点路径上weightB的最大值 如果加边过程中生成了环,则删除环中weightB最大的边 由于是无向图,点之间没有拓扑序, ...

  9. css3基础教程十三征服CSS3选择器

    :enabled选择器 在Web的表单中,有些表单元素有可用(“:enabled”)和不可用(“:disabled”)状态,比如输入框,密码框,复选框等.在默认情况之下,这些表单元素都处在可用状态.那 ...

  10. Java学习随笔——RMI

    RMI(Remote Method Invocation)远程方法注入,用来实现远程方法调用,是实现分布式技术的一种方法.RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建了和服务对象相同的方 ...