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框架中,检索策略主要涉及...
6. **Fetch Types**: 在Hibernate中,提供了多种方式来获取关联对象:`EAGER`(急切加载)和`LAZY`(惰性加载)。 #### 三、获取数据方法 - **load()**: 用于加载指定主键对应的实体对象。如果对象不在缓存中,则...
在讨论j2ee英文面试的时候,特别是涉及struts、spring、hibernate、oracle和agile这几个技术点时,我们将会讨论这些技术的概念、应用以及优缺点。 首先,Hibernate是一个开放源代码的对象关系映射(ORM)框架,它让...
1. **修改Fetch策略**:将Fetch策略设置为`fetch="join"`,即在查询主对象的同时通过JOIN查询的方式加载关联对象,这样就不会抛出延迟加载异常。 2. **禁用延迟加载**:将`lazy="false"`,这样就会在查询主对象时...
使用`fetch="select"`会禁用延迟加载,而`fetch="join"`则会导致连接查询,可能影响性能。 #### 四、注意事项 - **Session管理**:延迟加载的效果受限于Session的生命周期,确保在访问延迟加载的对象前,Session...
"select s from Student s join fetch s.teacher") .list(); ``` **3. 手动控制加载行为:** ```java List<Student> students = (List) session.createCriteria(Student.class) .setFetchMode("teacher", ...
为了避免这种情况,可以考虑使用`fetch="join"`或`fetch="select"`策略,前者会在加载实体时同时加载其所有关联实体,后者则按需加载。 #### 6. 映射策略 除了基本的`<many-to-one>`映射外,Hibernate还支持多种...
**HQL (Hibernate Query Language)** 是一种面向对象的查询语言,它允许开发人员使用类名和属性名来执行数据库查询,而不需要直接编写SQL语句。在进行多表检索时,HQL提供了多种连接方式,包括内连接、外连接等。 #...
这意味着"SeLeCT"、"sELEct"和"SELECT"都是等价的。然而,类名和属性名的大小写是敏感的,例如"org.hibernate.eg.FOO"并不等于"org.hibernate.eg.Foo",同样"foo.barSet"也不等于"foo.BARSET"。在本手册中,HQL的...
- **解决方法:** 在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 ...
在这个查询中,我们不仅检索了Cat实体,还通过LEFT JOIN FETCH子句同时加载了它们的mate和kittens。这种方式确保了即使mate或kittens为空,查询也能正确执行,同时避免了多次数据库访问,提高了查询效率。 #### 四...
- **使用 FetchMode.JOIN**:在 hbm.xml 映射文件中,将 fetch 属性设置为 JOIN,或者使用 @Fetch(FetchMode.JOIN) 注解。 ```xml <set name="orders" fetch="join"> <key column="user_id"/> ...
- 如果没有显式设置 lazy="false",则默认情况下 Hibernate 使用 Select Fetching,这意味着对于每个主对象,Hibernate 都会发送一个 SQL 查询来加载关联对象。 - 这种方式适用于关联数据量不大,且每次查询都需要...
需要注意的是,`fetch`连接不适用于滚动查询或迭代查询,且`full join fetch`和`right join fetch`通常没有实际意义。 4. **关联的处理**:HQL支持处理一对一、一对多、多对一和多对多的关联。例如,`from Cat as ...
N+1次SELECT查询问题源于Hibernate的默认行为。当从数据库中加载一个对象及其关联对象时,如果不做特别处理,Hibernate会为每个主对象单独执行一次查询来获取其关联对象,导致查询次数过多。以Customer和Order为例,...
应考虑使用`fetch="select"`或`fetch="join"`策略来控制加载行为。 **3. 延时加载的误用**:不合理的延时加载可能导致“懒加载地狱”,即在不期望的时候触发大量数据库请求。评估业务需求,合理设置加载策略,如...
因此,SeLeCT 和 sELEct 以及 SELECT 是相同的,但是 org.hibernate.eg.FOO 不等价于 org.hibernate.eg.Foo,同样,foo.barSet也不等价于 foo.BARSET。本手册中的 HQL 关键字将使用小写字母。 2. from 子句 HQL 中...
例如,`SeLeCT`、`sELEct`和`SELECT`被视为相同,但`org.hibernate.eg.FOO`不等于`org.hibernate.eg.Foo`,同理`foo.barSet`不等于`foo.BARSET`。 - **关键字书写**:在本手册中,HQL关键字使用小写字母。有些用户...
- **迫切左外连接检索(Fetch Join)**:兼顾透明性和效率,但可能加载不必要的对象,且复杂的表连接可能影响性能。 2. **查看Hibernate生成的SQL**:在`applicationConfig.xml`中设置`hibernate.show_sql`为`true...
例如,如果Table1和Table2存在一对多关系,我们可以在Table1的实体类中定义一个Table2类型的集合属性,然后通过`fetch`策略来一次性加载所有关联数据。 ```java @Entity public class Table1 { @OneToMany(mapped...