Java 加载Hibernate实体时如何优化Carstesian产品
为了演示我的问题,我创建了一个简单的Spring引导应用程序。它有一个实体,具有ID、两个字符串属性和两个集合 我跟踪了Hibernate,发现Cat是通过这个SQL从DB加载的Java 加载Hibernate实体时如何优化Carstesian产品,java,hibernate,jpa,spring-data,Java,Hibernate,Jpa,Spring Data,为了演示我的问题,我创建了一个简单的Spring引导应用程序。它有一个实体,具有ID、两个字符串属性和两个集合 我跟踪了Hibernate,发现Cat是通过这个SQL从DB加载的 select cat0_.id as id1_0_0_, cat0_.name as name2_0_0_, cat0_.sex as sex3_0_0_, colors1_.cat_id as cat_id1_1_1_, colors1_.color as color2_1_1_,
select cat0_.id as id1_0_0_,
cat0_.name as name2_0_0_,
cat0_.sex as sex3_0_0_,
colors1_.cat_id as cat_id1_1_1_,
colors1_.color as color2_1_1_,
nicknames2_.cat_id as cat_id1_2_2_,
nicknames2_.nickname as nickname2_2_2_
from cat cat0_
left outer join cat_color colors1_ on cat0_.id=colors1_.cat_id
left outer join cat_nickname nicknames2_ on cat0_.id=nicknames2_.cat_id
where cat0_.id=1
然后,Hibernate从cat表的行和两个表(表示CATColor和cat昵称集)中获取笛卡尔积
然后Hibernate遍历每一行,解析ResultSet的每一项并创建实体。是否有可能优化这种方法?由于严重的性能问题,我想通过子选择来选择CATColor和CAT昵称集。在实际情况中,我获取了1500个实体,这些实体具有复杂的结构,一个获取的实体在相应的ResultSet中生成了25000行,这导致了很长的解析时间
在我的例子中,延迟加载不是我想要使用的选项,因为它会给代码带来混乱。据我所知,延迟加载的集合必须通过第一次调用进行初始化,这在我的实际应用程序中是一个相当大的可用性代价
我希望有3个单独的选择,一个来自cat表,一个来自cat_颜色表,一个来自cat_昵称表。我找到了Hibernate的解决方案,@fetchMode.SELECT完成了这项工作,因为它使Hibernate通过单独的选择而不是联接来选择昵称
@Fetch(FetchMode.SELECT)
@ElementCollection(fetch = FetchType.EAGER)
@Column(name = "nickname")
@CollectionTable(
name = "cat_nickname",
joinColumns = @JoinColumn(name = "cat_id"))
private Set<String> nicknames;
你跟踪的请求在我看来很好,它不是我所说的笛卡尔积。其他哪个SQL请求将检索单个cat的数据?如果您不需要特定用例的外围数据,可以通过FetchType.LAZY剪切一些连接。在我的用例中,延迟加载不是我想要使用的选项,因为它会给代码带来混乱。据我所知,延迟加载的集合必须通过第一次调用进行初始化,这在我的实际应用程序中是一个相当大的可用性代价。其他哪个SQL请求将检索单个cat的数据?我希望有3个单独的选择,一个来自cat表,一个来自cat_颜色表,一个来自cat_昵称表。是的,通过使用FetchType.LAZY并用代码触发选择,您可以进行这3个单独的选择。你不能同时拥有一件事和另一件事。
select cat0_.id as id1_0_0_,
cat0_.name as name2_0_0_,
cat0_.sex as sex3_0_0_,
colors1_.cat_id as cat_id1_1_1_,
colors1_.color as color2_1_1_,
nicknames2_.cat_id as cat_id1_2_2_,
nicknames2_.nickname as nickname2_2_2_
from cat cat0_
left outer join cat_color colors1_ on cat0_.id=colors1_.cat_id
left outer join cat_nickname nicknames2_ on cat0_.id=nicknames2_.cat_id
where cat0_.id=1
id1_0_0_ name2_0_0_ sex3_0_0_ cat_id1_1_1_ color2_1_1_ cat_id1_2_2_ nickname2_2_2_
1 Ben Male 1 Black 1 Fluffy
1 Ben Male 1 Black 1 Catburger
1 Ben Male 1 Black 1 Mr. Tomcat
1 Ben Male 1 White 1 Fluffy
1 Ben Male 1 White 1 Catburger
1 Ben Male 1 White 1 Mr. Tomcat
@Fetch(FetchMode.SELECT)
@ElementCollection(fetch = FetchType.EAGER)
@Column(name = "nickname")
@CollectionTable(
name = "cat_nickname",
joinColumns = @JoinColumn(name = "cat_id"))
private Set<String> nicknames;