ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
# 19.1.2\. 调整抓取策略(Tuning fetch strategies) 查询抓取(默认的)在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()`方法取得数据。 * 只有在关联之间进行导航时,才会隐式的取得数据。 * `条件查询` * 使用了`subselect`抓取的HQL查询 不管你使用哪种抓取策略,定义为非延迟的类图会被保证一定装载入内存。注意这可能意味着在一条HQL查询后紧跟着一系列的查询。 通常情况下,我们并不使用映射文档进行抓取策略的定制。更多的是,保持其默认值,然后在特定的事务中, 使用HQL的`左连接抓取(left join fetch)` 对其进行重载。这将通知 Hibernate在第一次查询中使用外部关联(outer join),直接得到其关联数据。 在`条件查询` API中,应该调用 `setFetchMode(FetchMode.JOIN)`语句。 也许你喜欢仅仅通过条件查询,就可以改变`get()` 或 `load()`语句中的数据抓取策略。例如: ``` User user = (User) session.createCriteria(User.class) .setFetchMode("permissions", FetchMode.JOIN) .add( Restrictions.idEq(userId) ) .uniqueResult(); ``` (这就是其他ORM解决方案的“抓取计划(fetch plan)”在Hibernate中的等价物。) 截然不同的一种避免N+1次查询的方法是,使用二级缓存。