🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 19.1.5\. 使用批量抓取(Using batch fetching) Hibernate可以充分有效的使用批量抓取,也就是说,如果仅一个访问代理(或集合),那么Hibernate将不载入其他未实例化的代理。 批量抓取是延迟查询抓取的优化方案,你可以在两种批量抓取方案之间进行选择:在类级别和集合级别。 类/实体级别的批量抓取很容易理解。假设你在运行时将需要面对下面的问题:你在一个`Session`中载入了25个 `Cat`实例,每个`Cat`实例都拥有一个引用成员`owner`, 其指向`Person`,而`Person`类是代理,同时`lazy="true"`。 如果你必须遍历整个cats集合,对每个元素调用`getOwner()`方法,Hibernate将会默认的执行25次`SELECT`查询, 得到其owner的代理对象。这时,你可以通过在映射文件的`Person`属性,显式声明`batch-size`,改变其行为: ``` <class name="Person" batch-size="10">...</class> ``` 随之,Hibernate将只需要执行三次查询,分别为10、10、 5。 你也可以在集合级别定义批量抓取。例如,如果每个`Person`都拥有一个延迟载入的`Cats`集合, 现在,`Sesssion`中载入了10个person对象,遍历person集合将会引起10次`SELECT`查询, 每次查询都会调用`getCats()`方法。如果你在`Person`的映射定义部分,允许对`cats`批量抓取, 那么,Hibernate将可以预先抓取整个集合。请看例子: ``` <class name="Person"> <set name="cats" batch-size="3"> ... </set> </class> ``` 如果整个的`batch-size`是3(笔误?),那么Hibernate将会分四次执行`SELECT`查询, 按照3、3、3、1的大小分别载入数据。这里的每次载入的数据量还具体依赖于当前`Session`中未实例化集合的个数。 如果你的模型中有嵌套的树状结构,例如典型的帐单-原料结构(bill-of-materials pattern),集合的批量抓取是非常有用的。 (尽管在更多情况下对树进行读取时,_嵌套集合(nested set)_或_原料路径(materialized path)_(××) 是更好的解决方法。)