hibernate之优化抓取(选择抓取策略之通过联结即时抓取)

Hibernate优化抓取策略
本文介绍了Hibernate中通过联结即时抓取策略优化数据加载的方法。包括如何在映射元数据中启用即时抓取,以及使用左外联结SQL来确保即使没有关联记录也能正确加载实体。同时探讨了如何设置全局配置属性hibernate.max_fetch_depth来控制联结抓取的最大深度。
hibernate之优化抓取(选择抓取策略之通过联结即时抓取)

例如:每次我需要Item的时候,也需要该item的seller(User对象)。如果可以把它变成语句,就应该到映射元数据中去给seller关联启用即时抓取,并利用SQL联结:
 
现在hibernate在单个SQL语句中把Item和它的seller都加载了。例如:
 
这个操作触发了下列SQL SELECT:
 
很显然,seller不再被按需延迟加载,而是立即加载。因此,fetch="join"禁用了延迟加载。如果你只用lazy="false"启用即时抓取,会立即看到第二个SELECT。通过fetch="join",在同一个SELECT中加载seller。
上例生成的左外联结SQL中,如果Item没有卖主,所有u.*列都会被填上NULL。这就是为什么hibernate使用外部联结的原因,因此它不仅可以获取有卖主的Item对象,而且可以获取全部Item对象。如果你启用<many-to-one not-null="true"/>,hibernate就会执行一个内联结而不是外联结。
-----------
也可以在集合上设置即时联结抓取策略:
 
如果现在加载许多个Item对象,例如通过creatCriteria(Item.class).list(),产生的SQL语句看起来像这样:
 
----------
最后,必须介绍一个全局的、可以用来控制被联结的实体关联(不是集合)最大数量的Hibernate配置设置。考虑你已经在映射元数据中设置所有多对一和一对多关联映射为fetch="join"。假设Item有一个successfulBid关联,Bid有一个bidder,并且这个User有一个shippingAddress。如果所有这些关联都通过fetch="join"映射,那么当你加载Item时, 要联结多少张表,要获取多少数据?
在这种情况下,被联结的表的数量取决于全局的hibernate.max_fetch_depth配置属性。默认情况下,没有设置限制,因此加载Item也在单个查询中获取Bid,User和Address。合理的设置很小,通常在1--5之间。你甚至可以通过设置该属性为0,给多对一和一对一的关联禁用联结抓取!(注意有些数据库方言可以预设这项属性,如MySQLDialect把它设置为2.)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值