java springframework.data.jpa使用JpaSpecificationExecutor生成两次相同的连接
我正在使用JpaSpecificationExecutor,所以我使用org.springframework.data.jpa.domain.specification中的规范Api动态创建sql,问题是它两次生成相同的连接,这会降低性能,下面是代码: 调用方方法是:java springframework.data.jpa使用JpaSpecificationExecutor生成两次相同的连接,java,jpa,spring-data-jpa,Java,Jpa,Spring Data Jpa,我正在使用JpaSpecificationExecutor,所以我使用org.springframework.data.jpa.domain.specification中的规范Api动态创建sql,问题是它两次生成相同的连接,这会降低性能,下面是代码: 调用方方法是: private Specification<EntityA> toSpecEntityBAndEntityC(boolean withEntityBAndEntityC, Specification<Entity
private Specification<EntityA> toSpecEntityBAndEntityC(boolean withEntityBAndEntityC, Specification<EntityA> specs) {
if (withEntityBAndEntityC) {
specs = Specification.where(specs).and(EntityASpecs.withEntityB());
specs = Specification.where(specs).and(EntityASpecs.withEntityC());
}
return specs;
}
它生成这个查询
select *
from (select entityA0_.id as id1_4_0_,
entityC2_.filedOne as filedOne1_3_1_,
entityB3_.filedTwo as filedTwo1_1_2_,
entityA0_.filedFive_id as filedFive_id7_4_0_,
entityA0_.entityB_filedTwo as entityB_filedTwo8_4_0_,
entityA0_.DATE_TRAITEMENT as DATE_TRAITEMENT2_4_0_,
entityA0_.filedFour as filedFour3_4_0_,
entityA0_.entityC_filedOne as entityC_filedOne9_4_0_,
entityA0_.filedSix as filedSix4_4_0_,
entityA0_.filedSeven as filedSeven5_4_0_,
entityA0_.TEMPS_REPONSE as TEMPS_REPONSE6_4_0_,
entityC2_.NB_MOYEN_TRAITEMENTS as NB_MOYEN_TRAITEMEN2_3_1_,
entityC2_.filedSeven as filedSeven3_3_1_,
entityC2_.filedSixteen as filedSixteen4_3_1_,
entityB3_.filedFifteen as DATE_TRAITEMENT_SA2_1_2_,
entityB3_.filedEight as filedEight11_1_2_,
entityB3_.filedTen as filedTen3_1_2_,
entityB3_.filedNine as filedNine4_1_2_,
entityB3_.filedFourteen as filedFourteen5_1_2_,
entityB3_.filedThirteen as filedThirteen6_1_2_,
entityB3_.NUMERO_AUTORISATION as NUMERO_AUTORISATIO7_1_2_,
entityB3_.filedEleven as filedEleven8_1_2_,
entityB3_.filedSeven as filedSeven9_1_2_,
entityB3_.filedTwelve as filedTwelve10_1_2_
from entityA entityA0_
inner join entityB entityB1_ on entityA0_.entityB_filedTwo = entityB1_.filedTwo
inner join entityC entityC2_ on entityA0_.entityC_filedOne = entityC2_.filedOne
**inner join entityB entityB3_ on entityA0_.entityB_filedTwo = entityB3_.filedTwo**
where entityA0_.filedSix = 'Value'
and (entityB1_.filedFifteen between TO_DATE('2018-11-08 14:00:00', 'YYYY-MM-DD HH24:MI:SS') and TO_DATE('2018-11-08 15:00:00', 'YYYY-MM-DD HH24:MI:SS'))
order by entityA0_.DATE_TRAITEMENT desc)
;
注意:
重复连接在两个星星之间
**inner join entityB entityB3_ on entityA0_.entityB_filedTwo = entityB3_.filedTwo**
初始规范是如何构建的?我指的是由
spects
参数传递到tospecitybandentityc
方法中的一个。它的构造类似于规范toSpecs(boolean with antitybandentitic){Specification specs=Specification.where(null);我首先将断点放在JoinScope::addJoin()处
并跟踪来自意外来源的呼叫
select *
from (select entityA0_.id as id1_4_0_,
entityC2_.filedOne as filedOne1_3_1_,
entityB3_.filedTwo as filedTwo1_1_2_,
entityA0_.filedFive_id as filedFive_id7_4_0_,
entityA0_.entityB_filedTwo as entityB_filedTwo8_4_0_,
entityA0_.DATE_TRAITEMENT as DATE_TRAITEMENT2_4_0_,
entityA0_.filedFour as filedFour3_4_0_,
entityA0_.entityC_filedOne as entityC_filedOne9_4_0_,
entityA0_.filedSix as filedSix4_4_0_,
entityA0_.filedSeven as filedSeven5_4_0_,
entityA0_.TEMPS_REPONSE as TEMPS_REPONSE6_4_0_,
entityC2_.NB_MOYEN_TRAITEMENTS as NB_MOYEN_TRAITEMEN2_3_1_,
entityC2_.filedSeven as filedSeven3_3_1_,
entityC2_.filedSixteen as filedSixteen4_3_1_,
entityB3_.filedFifteen as DATE_TRAITEMENT_SA2_1_2_,
entityB3_.filedEight as filedEight11_1_2_,
entityB3_.filedTen as filedTen3_1_2_,
entityB3_.filedNine as filedNine4_1_2_,
entityB3_.filedFourteen as filedFourteen5_1_2_,
entityB3_.filedThirteen as filedThirteen6_1_2_,
entityB3_.NUMERO_AUTORISATION as NUMERO_AUTORISATIO7_1_2_,
entityB3_.filedEleven as filedEleven8_1_2_,
entityB3_.filedSeven as filedSeven9_1_2_,
entityB3_.filedTwelve as filedTwelve10_1_2_
from entityA entityA0_
inner join entityB entityB1_ on entityA0_.entityB_filedTwo = entityB1_.filedTwo
inner join entityC entityC2_ on entityA0_.entityC_filedOne = entityC2_.filedOne
**inner join entityB entityB3_ on entityA0_.entityB_filedTwo = entityB3_.filedTwo**
where entityA0_.filedSix = 'Value'
and (entityB1_.filedFifteen between TO_DATE('2018-11-08 14:00:00', 'YYYY-MM-DD HH24:MI:SS') and TO_DATE('2018-11-08 15:00:00', 'YYYY-MM-DD HH24:MI:SS'))
order by entityA0_.DATE_TRAITEMENT desc)
;
**inner join entityB entityB3_ on entityA0_.entityB_filedTwo = entityB3_.filedTwo**