fetch检索策略用来说明如何把关联对象加载上来!例如使用单独的select语句来加载关联对象;或者使用左外连接加载当前对象和关联对象。
在单边中设置fetch=join时,由于在加载当前对象时会同时加载关联对象,那么就不可能等到使用关联对象时才去加载关联对象。此时Hibernate使用左外连接加载当前对象和关联对象,这会使关联对象的lazy=true失效。
这里我们使用Order和Customer来说明。其中一个Customer中可以有有多个Order,建立相应的实体类和.hbm.xml文件,在Order.hbm.xml中我们把<many-to-one>元素的fetch属性设置为join;
<many-to-one name="customer" column="customerid" fetch="join"/>
下面是加载Order对象的测试代码:
Order o = (Order)session.load(Order.class, 1);
o.getOrderNumber();
Customer c = o.getCustomer();
c.getName();
下面是代码执行结果:
Hibernate: select order0_.id as id1_1_, order0_.orderNumber as orderNum2_1_1_, order0_.customerid as customerid1_1_, customer1_.id as id0_0_, customer1_.name as name0_0_ from orders order0_ left outer join customer customer1_ on order0_.customerid=customer1_.id where order0_.id=?
结果分析:
1.在执行sesseion.load()方法时不会去加载Order对象,更不会加载关联对象Customer。原因是<class>元素的lazy默认为true,只有在使用Order对象时才会加载Order对象
2.在执行o.getOrderNumber()时会使用左外连接加载Order对象,以及Order所关联的Customer对象。原因是<many-to-one>的fetch的值为join。
若此时fetch=select,则此时会输出
Hibernate: select order0_.id as id1_0_, order0_.orderNumber as orderNum2_1_0_, order0_.customerid as customerid1_0_ from orders order0_ where order0_.id=?
Hibernate: select customer0_.id as id0_0_, customer0_.name as name0_0_ from customer customer0_ where customer0_.id=?
3.在执行o.getOrderNumber()时,Hibernate会加载Order对象,但不会加载相关联对象Customer,原因是<many-to-one>元素的fetch属性值为select。
4.在执行o.getCustomer()方法时也不会加载Customer对象,因为这时还没有使用Customer对象。如果Customer对应的<class>元素的lazy=false时,效果就不一样了,在执行o.getOrderNumber()方法时就会使用左外连接加载Order对象,以及关联对象Customer。也就是说,关联对象的类级别lazy=false时,那么fetch的默认值为join。
5.在执行c.getName()时执行一条select语句来加载Customer对象
在集合一端中使用fetch属性,它的可选值为:join、select、subselect三种。默认值为select。
<set>的fetch=select或fetch=join时,基本与<many-to-one>是相同的,但也有一点不同。在单边fetch中,如果关联对象的类级别lazy=false时,那么fetch的默认值为join,但在集合fetch中,fetch的默认值总是select。
当fetch=subselect时,来测试上会的例子,我们会发现这与fetch=select没有任何区别。这是因为subselect只有在使用HQL时才会有效果
String hql = "from Customer c where c.id in (1,2)";
List<Customer> cList = session.createQuery(hql).list();
for(Customer c : cList) {
c.getName();
Set<Order> orders = c.getOrders();
orders.iterator();
}
结果为:
Hibernate: select customer0_.id as id0_, customer0_.name as name0_ from customer customer0_ where customer0_.id in (1 , 2)
Hibernate: select orders0_.customerid as customerid1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.orderNumber as orderNum2_1_0_, orders0_.customerid as customerid1_0_ from orders orders0_ where orders0_.customerid=?
Hibernate: select orders0_.customerid as customerid1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.orderNumber as orderNum2_1_0_, orders0_.customerid as customerid1_0_ from orders orders0_ where orders0_.customerid=?
结果分析:
1.在执行session.createQuery(hql).list()时,会执行一条SQL语句来加载两个Customer对象,但不会加载关联对象;
2. 在每次执行orders.iteraotr()时会执行一条SQL语句来加载当前Customer对象的关联对象。因为一共有两个Customer对象,所以会执行两条加载关联对象的SQL语句。
把<set>元素的fetch设置为subselect,再次执行上面的代码,结果如下:
Hibernate: select customer0_.id as id0_, customer0_.name as name0_ from customer customer0_ where customer0_.id in (1 , 2)
Hibernate: select orders0_.customerid as customerid1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.orderNumber as orderNum2_1_0_, orders0_.customerid as customerid1_0_ from orders orders0_ where orders0_.customerid in (select customer0_.id from customer customer0_ where customer0_.id in (1 , 2))
1.在执行session.createQuery(hql).list()时,会执行一条SQL语句来加载两个Customer对象,但不会加载关联对象。这与上面是一样的,没有什么区别
2.在第一次执行orders.iteraotr()时会执行一条子查询的SQL语句,它会一次性的加载当前List中所有Customer对象的关联对象。所以在下一次再执行orders.iteraotr()时就不会再执行SQL语句了
分享到:
相关推荐
本笔记将聚焦于Hibernate中的类级别检索策略以及`lazy`、`fetch`和`batch-size`这三个属性的使用,帮助开发者更高效地管理数据库查询。 1. **懒加载(Lazy Loading)** `lazy`属性是Hibernate的懒加载机制,用于...
标题:“HIBERNATE检索策略” 描述:本文深入解析了HIBERNATE的检索策略,为读者提供了一条清晰的学习路径,重点分析了HIBERNATE中的抓取策略及其应用场景,帮助开发者更有效地管理和优化数据加载过程。 在...
### Hibernate的检索策略详解 #### 一、概述 在Java持久化框架Hibernate中,检索策略是一种重要的机制,它主要用于控制对象何时以及如何加载到应用程序内存中。合理的检索策略不仅可以提高应用性能,还能简化代码...
检索方式及策略”这一主题中,我们将深入探讨如何在Hibernate 5中有效地检索数据以及相关的检索策略。 一、Hibernate检索方式 1. **HQL(Hibernate Query Language)**: HQL是Hibernate提供的面向对象的查询语言,...
OracleFetch通过定义的数据流和安全策略,自动从Oracle数据库中抽取数据,将其转换为IDOL服务器可以理解的格式。这一功能极大地简化了数据整合的过程,使企业能够更高效地管理和利用其数据资产。 #### 2.2 系统架构...
2. Axios或Fetch:进行异步数据请求,从服务器获取文献数据或发送检索请求。 3. Redux或Vuex:管理应用程序的状态,保持数据的一致性。 4. Bootstrap或Material UI:提供现成的UI组件,快速搭建美观的界面。 五、...
"可能指的是在LabVIEW中用于从数据库检索数据的特定函数。这个函数可能用于一次性获取多条记录,或者在执行查询后持续获取结果集的一部分,这对于处理大量数据时能提高性能。 3. **SQL查询**:在LabVIEW中,你可以...
总结起来,实现一个类似于百度检索功能的JS应用,需要前端JavaScript的自动补全功能、异步请求处理,后端服务器与数据库的交互,以及合理的数据库设计和安全策略。这个过程涉及的技术广泛,包括DOM操作、Ajax/Fetch ...
"20_newsgroups"数据集是一个广泛用于文本分类和信息检索研究的经典数据集,由20个不同的新闻组(如sci.space、rec.sport.hockey等)的帖子组成,大约包含2万条消息。这个数据集的特点是主题多样,涵盖了各种话题,...
这个数据集最初是由卡内基梅隆大学的Tom Mitchell教授和他的研究团队创建的,用于研究文本分类和信息检索技术。它的主要特点在于包含了多种主题,覆盖了20个不同的新闻类别,这些类别包括汽车、烹饪、电子设备、体育...
例如,可以使用`.on('input', function() {...})`监听输入事件,然后使用Ajax或Fetch API向服务器发送异步请求。服务器端可能基于某种搜索算法(如Trie树、倒排索引或模糊匹配)返回匹配数据,这些数据再由...
此外,我们还可以在实体映射文件中通过`lazy="true"`或`fetch="join"`等属性来设定默认的检索策略。但需要注意,过度使用迫切加载可能导致大数据量的内存消耗,因此应结合具体业务场景选择合适的检索策略。 总结,...
在SQL Server数据库管理系统中,高性能的分页存储过程是一个关键的优化策略,它主要用于处理大量数据的查询场景,如报表展示、数据浏览等。当数据量过大无法一次性加载时,分页检索能有效地提高用户体验,同时减少...
在这个特定的项目中,我们关注的是使用JSON格式进行数据传输和缓存策略来实现自动检索提示的功能。以下是关于这个主题的详细解释: **JSON(JavaScript Object Notation)**: JSON是一种轻量级的数据交换格式,...
学习成长路,Hibernate总结: 1.Hibernate入门优缺点、 2.Hibernate的操作CRUD、 3.主键生成机制、 4.持久化对象的状态、 ...8.Hibernate检索策略(fetch抓取策略)、 9.二级缓存、 10.Hbernate的检索方式(HQL语句)
通过这个网站,用户可以轻松地检索到任何GitHub用户的公开仓库信息,而无需进行复杂的API调用或者编写代码。只需要输入GitHub用户名,点击按钮,就能获得该用户拥有的存储库数量,并且每个存储库都有直接的访问链接...
为了解决 n+1 问题,Hibernate 提供了其他两种检索策略:延迟检索策略和迫切左外连接检索策略。延迟检索策略能避免多余加载应用程序不需要访问的关联对象,迫切左外连接检索策略则充分利用了 SQL 的外连接查询功能,...
16.6 在应用程序中显式指定迫切左外连接检索策略 16.7 属性级别的检索策略 16.8 小结 16.9 思考题 第17章 Hibernate的检索方式(上) 17.1 Hibernate的检索方式简介 17.1.1 HQL检索方式 17.1.2 QBC...
16.6 在应用程序中显式指定迫切左外连接检索策略 16.7 属性级别的检索策略 16.8 小结 16.9 思考题 第17章 Hibernate的检索方式(上) 17.1 Hibernate的检索方式简介 17.1.1 HQL检索方式 17.1.2 QBC...