我在一些旧代码中发现了奇怪的东西(至少对我来说)。
被注释的字段也被@ManyToOne
注释了@BatchSize
。
我一直认为@BatchSize
注解只影响在类级别或集合()上注解,并在迭代时@OneToMany
影响预取。
但也许我错了,注释@ManyToOne
会@BatchSize
影响某些东西。我在文档中找不到答案。
@ManyToOne
用注释@BatchSize
有意义吗?
我在一些旧代码中发现了奇怪的东西(至少对我来说)。
被注释的字段也被@ManyToOne
注释了@BatchSize
。
我一直认为@BatchSize
注解只影响在类级别或集合()上注解,并在迭代时@OneToMany
影响预取。
但也许我错了,注释@ManyToOne
会@BatchSize
影响某些东西。我在文档中找不到答案。
@ManyToOne
用注释@BatchSize
有意义吗?
我认为这个问题是指在同一领域结合@ManyToOne
和,例如:@BatchSize
@ManyToOne
@BatchSize(size = 5)
private User owner;
Hibernate 不支持这个用例,至少在使用注解时是这样。文档中提到的批量获取的唯一用途是:
@OneToMany
或@ManyToMany
(但不是 @ManyToOne
)例如:
@Entity
@BatchSize(size = 5)
public class User {
...
}
后一种情况支持对所有用户类型的关系进行批处理,包括多对一关系。但是,使用实体类上的注释,不可能逐个字段地控制行为。
在 Hibernate 源代码中搜索所有用途,@BatchSize
确认您的使用缺乏支持。从我在AnnotationBinder.java中看到的,@BatchSize
仅在实体类和具有某种注释的字段上检查@XxxToMany
注释。
@ManyToOne
@BatchSize
仅当相应字段标记为lazy
( lazy=true
)时,关联才有意义。
实际上,如果该字段不是lazy
,则根据定义,自从加载了封闭实体以来,它就已经加载了,因此数据库调用的问题不适用。
想象一个Person
有一个ShoesPair
元素集合(ShoesPair
.class)的类,并且在这个集合中存在一个owner
标记为惰性的字段(因为是可选的,并且在检索特定的一双鞋时并没有真正带来重要信息)。
一个人想要遍历25双鞋(25 个ShoesPair
对象)以检索它们的所有者。
如果owner
字段(对应一个人)仅用 注释@ManyToOne
,则将有25 个选择到数据库。
但是,如果使用 注释,则只@BatchSize(size=5)
会有5次调用,从而提高性能。
从Hibernate 文档中,确切地说批量大小不仅适用于集合:
您还可以启用集合的批量获取。
Hibenate 尤其提到@OneToMany
了案例,因为这些案例应用于 90% 的案例中标记为 的字段lazy
。
用 Hibernate 解决 N+1 查询问题
1 使用带有 fetchMode 的条件查询
条件标准 = session.createCriteria(Customer.class); criteria.setFetchMode("联系人", FetchMode.EAGER);
2 HOL 获取连接
3 @BatchSize
@BatchSize 注释可用于定义在单个数据库查询中填充多少相同的关联。如果会话附加了 100 个客户,并且“联系人”集合的映射使用大小为 n 的 @BatchSize 进行注释。这意味着每当 Hibernate 需要填充惰性联系人集合时,它会检查会话,如果它有更多客户需要填充他们的联系人集合,它会获取最多 n 个集合。
@OneToMany(mappedBy="customer",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@BatchSize(size=25)
private Set<Contact> contacts = new HashSet<Contact>();