`

Hibernate的fetch="join"和fetch="select"

阅读更多

fetch参数指定了关联对象抓取的方式是select查询还是join查询,select方式时先查询返回要查询的主体对象(列表),再根据关联外键id,每一个对象发一个select查询,获取关联的对象,形成n+1次查询;
而join方式,主体对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询。
如果你的关联对象是延迟加载的,它当然不会去查询关联对象。
另外,在hql查询中配置文件中设置的join方式是不起作用的(而在所有其他查询方式如get、criteria或再关联获取等等都是有效的),会使用select方式,除非你在hql中指定join fetch某个关联对象。

 

fetch策略用于定义 get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。

fetch策略用于定义 get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。

在某种特殊的场合下,fetch在hql中还是起作用的。
例如
现有message(回帖)-->topic(主贴)-->forum(版块) 的多级many-to-one结构:
第一级:message-->topic many-to-one配置lazy="false" fetch="join"
第二级:topic-->forum many-to-one配置lazy="false" fetch="join"

这时如果"from message",则第二级:topic-->forum中的fetch策略会起作用

 

查询抓取(默认的)在N+1查询的情况下是极其脆弱的,因此我们可能会要求在映射文档中定义使用连接抓取:

 

<set name="permissions"
fetch="join">
<key column="userId"/>
<one-to-many class="Permission"/>
</set
<many-to-one name="mother" class="Cat" fetch="join"/>
在映射文档中定义的抓取策略将会有产生以下影响:

通过get()或load()方法取得数据。

只有在关联之间进行导航时,才会隐式的取得数据(延迟抓取)。

条件查询

在映射文档中显式的声明 连接抓取做为抓取策略并不会影响到随后的HQL查询。

通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中, 使用HQL的左连接抓取(left join fetch) 对其进行重载。这将通知 Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。 在条件查询 API中,应该调用 setFetchMode(FetchMode.JOIN)语句。

其实这并不能说明hql能够按照配置文件设置的join进行抓取,这时 第二级:topic-->forum 的抓取其实已经和hql没有关系了,因为前面已经产生了另一个select方式的抓取语句。
而是对象的关联获取,假如查询message时topic是设置为延迟加载的,那么在后面获取message.topic时,如topic.forum不延迟加载,那么topic-->forum会实现配置的join方式的抓取,这个显然和hql查询没有关系。

分享到:
评论

相关推荐

    HIBERNATE检索策略

    描述:本文深入解析了HIBERNATE的检索策略,为读者提供了一条清晰的学习路径,重点分析了HIBERNATE中的抓取策略及其应用场景,帮助开发者更有效地管理和优化数据加载过程。 在HIBERNATE框架中,检索策略主要涉及...

    Hibernate笔记

    6. **Fetch Types**: 在Hibernate中,提供了多种方式来获取关联对象:`EAGER`(急切加载)和`LAZY`(惰性加载)。 #### 三、获取数据方法 - **load()**: 用于加载指定主键对应的实体对象。如果对象不在缓存中,则...

    j2ee英文面试

    在讨论j2ee英文面试的时候,特别是涉及struts、spring、hibernate、oracle和agile这几个技术点时,我们将会讨论这些技术的概念、应用以及优缺点。 首先,Hibernate是一个开放源代码的对象关系映射(ORM)框架,它让...

    Hibernate延迟加载以及利用Spring

    1. **修改Fetch策略**:将Fetch策略设置为`fetch="join"`,即在查询主对象的同时通过JOIN查询的方式加载关联对象,这样就不会抛出延迟加载异常。 2. **禁用延迟加载**:将`lazy="false"`,这样就会在查询主对象时...

    Hibernate 1+N问题详解

    "select s from Student s join fetch s.teacher") .list(); ``` **3. 手动控制加载行为:** ```java List&lt;Student&gt; students = (List) session.createCriteria(Student.class) .setFetchMode("teacher", ...

    hibernate_many2one

    为了避免这种情况,可以考虑使用`fetch="join"`或`fetch="select"`策略,前者会在加载实体时同时加载其所有关联实体,后者则按需加载。 #### 6. 映射策略 除了基本的`&lt;many-to-one&gt;`映射外,Hibernate还支持多种...

    Hibernate延迟加载

    使用`fetch="select"`会禁用延迟加载,而`fetch="join"`则会导致连接查询,可能影响性能。 #### 四、注意事项 - **Session管理**:延迟加载的效果受限于Session的生命周期,确保在访问延迟加载的对象前,Session...

    hibernate 框架的基础四

    **HQL (Hibernate Query Language)** 是一种面向对象的查询语言,它允许开发人员使用类名和属性名来执行数据库查询,而不需要直接编写SQL语句。在进行多表检索时,HQL提供了多种连接方式,包括内连接、外连接等。 #...

    Hibernate HQL.doc

    这意味着"SeLeCT"、"sELEct"和"SELECT"都是等价的。然而,类名和属性名的大小写是敏感的,例如"org.hibernate.eg.FOO"并不等于"org.hibernate.eg.Foo",同样"foo.barSet"也不等于"foo.BARSET"。在本手册中,HQL的...

    hibernate优化前的程序

    应考虑使用`fetch="select"`或`fetch="join"`策略来控制加载行为。 **3. 延时加载的误用**:不合理的延时加载可能导致“懒加载地狱”,即在不期望的时候触发大量数据库请求。评估业务需求,合理设置加载策略,如...

    hibernate延迟加载技术详细解

    - 如果没有显式设置 lazy="false",则默认情况下 Hibernate 使用 Select Fetching,这意味着对于每个主对象,Hibernate 都会发送一个 SQL 查询来加载关联对象。 - 这种方式适用于关联数据量不大,且每次查询都需要...

    Hibernate问题解决

    - **解决方法:** 在Hibernate中,可以通过HQL或者Criteria API来实现`LEFT JOIN`和`RIGHT JOIN`。 - **LEFT JOIN:** ```java String hql = "FROM UserInfo u LEFT JOIN FETCH u.role r WHERE r.description ...

    Hibernate_HQL大全

    在这个查询中,我们不仅检索了Cat实体,还通过LEFT JOIN FETCH子句同时加载了它们的mate和kittens。这种方式确保了即使mate或kittens为空,查询也能正确执行,同时避免了多次数据库访问,提高了查询效率。 #### 四...

    hibernate-release-5.0.7.Final.zip官方

    - **使用 FetchMode.JOIN**:在 hbm.xml 映射文件中,将 fetch 属性设置为 JOIN,或者使用 @Fetch(FetchMode.JOIN) 注解。 ```xml &lt;set name="orders" fetch="join"&gt; &lt;key column="user_id"/&gt; ...

    hibernate的n+1问题.docx

    N+1次SELECT查询问题源于Hibernate的默认行为。当从数据库中加载一个对象及其关联对象时,如果不做特别处理,Hibernate会为每个主对象单独执行一次查询来获取其关联对象,导致查询次数过多。以Customer和Order为例,...

    hibernate的hql语句

    需要注意的是,`fetch`连接不适用于滚动查询或迭代查询,且`full join fetch`和`right join fetch`通常没有实际意义。 4. **关联的处理**:HQL支持处理一对一、一对多、多对一和多对多的关联。例如,`from Cat as ...

    HQL Hibernate查询语言

    因此,SeLeCT 和 sELEct 以及 SELECT 是相同的,但是 org.hibernate.eg.FOO 不等价于 org.hibernate.eg.Foo,同样,foo.barSet也不等价于 foo.BARSET。本手册中的 HQL 关键字将使用小写字母。 2. from 子句 HQL 中...

    hibernate hql基本操作

    例如,`SeLeCT`、`sELEct`和`SELECT`被视为相同,但`org.hibernate.eg.FOO`不等于`org.hibernate.eg.Foo`,同理`foo.barSet`不等于`foo.BARSET`。 - **关键字书写**:在本手册中,HQL关键字使用小写字母。有些用户...

    hibernate多表查询详解

    例如,如果Table1和Table2存在一对多关系,我们可以在Table1的实体类中定义一个Table2类型的集合属性,然后通过`fetch`策略来一次性加载所有关联数据。 ```java @Entity public class Table1 { @OneToMany(mapped...

    hibernate面试题2

    - **迫切左外连接检索(Fetch Join)**:兼顾透明性和效率,但可能加载不必要的对象,且复杂的表连接可能影响性能。 2. **查看Hibernate生成的SQL**:在`applicationConfig.xml`中设置`hibernate.show_sql`为`true...

Global site tag (gtag.js) - Google Analytics