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. MYSQL 缓存详解 [myownstars] 经典博客

    http://blog.itpub.net/15480802/viewspace-755582/ 在服务器级别只提供了query cache,而在存储引擎级别,MyISAM和InnoDB分别引入了ke ...

  2. Mysql重要配置参数的整理2

    http://ssydxa219.iteye.com/category/209848 下面开始优化下my.conf文件(这里的优化只是在mysql本身的优化,之前安装的时候也要有优化) cat /et ...

  3. systrace跟踪 Android性能优化

    http://blog.csdn.net/oujunli/article/details/8138172 http://blog.csdn.net/oujunli/article/details/50 ...

  4. 观察者模式在ng(Angular)中的应用

    在这个前端框架满天飞的天下,angular MVVM 的模式确实火了一把,所以最近一直在学习ng,感悟颇多,填坑无数,今天终静下心来打算更新自己久未变动的博客,做一做总结. 1.在ng中的观察者模式: ...

  5. jersey + tomcat 实现restful风格

    本文参考 http://www.cnblogs.com/bluesfeng/archive/2010/10/28/1863816.html 环境: idea 15.0.2 jersey 1.3 tom ...

  6. cordova 消息推送,告别,消息推送服务器,和 苹果推送证书

    cordova plugin add org.apache.cordova.vibration cordova plugin add https://github.com/katzer/cordova ...

  7. unlocker208安装之后看不到Apple macos选项,解决办法.

    前段时间升级了win10,最新的unlocker208安装以后看不到mac os的选项,为什么呢?我们在管理员允许win-install.cmd的过程中,会在cmd中看到这么一句话:LookupErr ...

  8. oracle的安装与plsql的环境配置

    1,首先得有oracle的安装包和plsql的安装包,安装包地址可见百度云 http://pan.baidu.com/s/1miTqhmg 2.解压下来进入0817账套,找到set.exe文件,双击安 ...

  9. struts_ognl详解

  10. GridView中某一列值的总和(web)

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)    {        if (e.Row.R ...