hibernate的@BatchSize注释允许批量提取延迟加载的实体。例如。如果我有类似的东西:
public class Product {
@OneToMany(fetchType=LAZY)
@BatchSize(size=10)
private ProductCategory category;
}
现在,如果我获得产品的类别,Hibernate将获取最多十个产品的类别,这些产品在当前会话中并且尚未初始化其类别字段。这样可以节省大量SQL调用数据库。到现在为止还挺好。现在我想知道为什么我不会在每个延迟加载的关系上使用@BatchSize注释?毕竟我为什么要对数据库进行额外调用?显然必须有这样的原因,否则Hibernate的人可能会把它作为默认值,但我目前看不到它。
答案 0 :(得分:18)
我不会直接回答你的问题,但我会回答一个更通用的问题,可能是“我找到了一些对我来说更快的东西,为什么不在任何地方应用呢?”
简短的回答是:你不应该进行优先购买。
hibernate是一个很棒的ORM,允许所有类型的优化。您应该测量导致问题的所有过程(经典N+1即使它很快,任何缓慢的过程等)并优化以解决它。
通过急切加载某些属性可能会获得更好的性能,因为您总是使用它们,对于其他属性,您可能需要100 BatchSize
,因为您知道它与您对该属性的关系数量有关。
最终,除非您需要关心它,否则您不应该关心优化。当你完成测量并发现问题时,你需要关心。
答案 1 :(得分:8)
为什么我不会在每个延迟加载的关系上使用@BatchSize注释?
因为它是一种优化,您可能不需要在每种情况下。当您的应用程序要访问许多不同product.category
的{{1}}时,这样的批量提取非常有用,因此您可以执行单个products
查询,而不是N个。
但是,如果您的应用程序在select from category...
个实例访问product.category
时,它不可能访问同一会话中其他Product
个实例的category
字段?如果您为该关联启用了Product
,那么您刚刚在会话中加载了许多其他@BatchSize
个实例而无法获得收益 - 它们永远不会被使用。