Fer*_*nch 6 optimization hibernate join hql criteria
我一直在尝试HQL和Criteria的不同组合,但我无法避免一些不必要的连接(在两者中)和一些不必要的选择(在Criteria中).
在我们的场景中,我们在Segment和Application实体之间有一个@ManyToMany关系(导航是从Segment到Applications).
首先我尝试了这个标准:
Application app = ...
List<Segment> segments = session.createCriteria(Segment.class)
.createCriteria(Segment.APPLICATIONS)
.add(Restrictions.idEq(app.getId()))
.list();
Run Code Online (Sandbox Code Playgroud)
Wich生成这个SQL:
select
this_.id as id1_1_,
this_.description as descript2_1_1_,
this_.name as name1_1_,
applicatio3_.segment_id as segment1_1_,
applicatio1_.id as app2_, <==== unnecessary APPLICATIONS columns
applicatio1_.id as id7_0_,
applicatio1_.name as name7_0_,
applicatio1_.accountId as accountId7_0_,
applicatio1_.applicationFlags as applicat5_7_0_,
applicatio1_.description_ as descript6_7_0_,
from
SEGMENTS this_
inner join
SEGMENTS_APPLICATIONS applicatio3_
on this_.id=applicatio3_.segment_id
inner join <==== unnecessary join
APPLICATIONS applicatio1_
on applicatio3_.app_id=applicatio1_.id
where
applicatio1_.id = ?
Run Code Online (Sandbox Code Playgroud)
如您所见,Criteria从APPLICATIONS中选择我不想被选中的列.我还没有找到办法(可能吗?).此外,它与APPLICATIONS连接,我认为这不是必需的,因为应用程序ID已经在连接表SEGMENTS_APPLICATIONS中(HQL也是如此).
(另外一个疑问,我想知道一个直接使用应用程序的限制,而不是app.getId().正如您将看到的,我可以在查询的HQL版本中执行此操作)
由于我无法限制选择部分(我不需要应用程序属性),我使用"select"子句尝试了这个HQL:
Application app = ...
List<Segment> segments = session.createQuery(
"select s from Segment s join s.applications as app where app = :app")
.setParameter("app", app)
.list();
Run Code Online (Sandbox Code Playgroud)
产生:
select
segment0_.id as id1_,
segment0_.description as descript2_1_,
segment0_.name as name1_,
from
SEGMENTS segment0_
inner join
SEGMENTS_APPLICATIONS applicatio1_
on segment0_.id=applicatio1_.segment_id
inner join <==== unnecessary join
APPLICATIONS applicatio2_
on applicatio1_.app_id=applicatio2_.id
where
applicatio2_.id=?
Run Code Online (Sandbox Code Playgroud)
您可以看到HQL没有从Application中选择属性(感谢"select s"部分),但仍然加入了APPLICATIONS表,我认为这是不必要的.我们怎么能避免这种情况?
(作为旁注,注意在HQL中我可以直接使用app,而不是像Criteria中那样使用app.getId())
你能帮我找到一种方法来避免Criteria中的"选择"和Criteria和HQL中不必要的"连接"吗?
(这个例子是@ManyToMany,但我认为它也适用于@OneToMany以及@ManyToOne和@OneToOne,即使使用fetch = LAZY).
非常感谢,Ferran
| 归档时间: |
|
| 查看次数: |
2660 次 |
| 最近记录: |