我用静态方法创建了一个返回Querydsl BooleanExpressions的类,所以我可以简单地将这些表达式传递给Spring Data存储库中的findAll()
或findOne()
方法,并在整个我的方法中重用它们。应用。就像这里:http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-five-querydsl/。
我遇到的问题是从我的方法返回的BooleanExpression正在生成看似次优的查询(至少在我的情况下)。
返回BooleanExpression的方法:
public static BooleanExpression byExternalIdAndProviderId(
final String externalId, final Long providerId) {
QEListing listing = QEListing.eListing;
return listing.externalIds.any().externalId.equalsIgnoreCase(externalId)
.and(listing.externalIds.any().provider.id.eq(providerId));
}
生成的查询:
select elisting0_.id as id1_24_,
elisting0_.address1 as address2_24_,
elisting0_.address2 as address3_24_,
elisting0_.business_name as business4_24_,
elisting0_.city_id as city10_24_,
elisting0_.created_date as created5_24_,
elisting0_.latitude as latitude6_24_,
elisting0_.longitude as longitud7_24_,
elisting0_.master_ext_id as master11_24_,
elisting0_.modified_date as modified8_24_,
elisting0_.state_id as state12_24_,
elisting0_.zip as zip13_24_,
elisting0_.zip_4 as zip9_24_,
elisting0_1_.vanity_name as vanity1_34_,
elisting0_2_.account_id as account1_2_
from listings elisting0_
left outer join vanity_names elisting0_1_ on elisting0_.id=elisting0_1_.listing_id
left outer join accounts_to_listings elisting0_2_ on elisting0_.id=elisting0_2_.listing_id
where (
exists (
select 1
from external_ids eexternali1_
where (
eexternali1_.id in (
select externalid2_.external_id
from listing_to_external_id externalid2_
where elisting0_.id=externalid2_.listing_id))
and lower(eexternali1_.external_id)='123456'
)
)
and (
exists (
select 1
from external_ids eexternali3_
where (
eexternali3_.id in (
select externalid4_.external_id
from listing_to_external_id externalid4_
where elisting0_.id=externalid4_.listing_id
)
)
and eexternali3_.provider_id=1
)
)
与此类似:
select elisting0_.id as id1_24_,
elisting0_.address1 as address2_24_,
elisting0_.address2 as address3_24_,
elisting0_.business_name as business4_24_,
elisting0_.city_id as city10_24_,
elisting0_.created_date as created5_24_,
elisting0_.latitude as latitude6_24_,
elisting0_.longitude as longitud7_24_,
elisting0_.master_ext_id as master11_24_,
elisting0_.modified_date as modified8_24_,
elisting0_.state_id as state12_24_,
elisting0_.zip as zip13_24_,
elisting0_.zip_4 as zip9_24_,
elisting0_1_.vanity_name as vanity1_34_,
elisting0_2_.account_id as account1_2_
from listings elisting0_
left outer join vanity_names elisting0_1_ on elisting0_.id=elisting0_1_.listing_id
left outer join accounts_to_listings elisting0_2_ on elisting0_.id=elisting0_2_.listing_id
join listing_to_external_id a on elisting0_.id = a.listing_id
join external_ids b on a.external_id = b.id
where lower(b.external_id) = '123456'
and b.provider_id = 1
有没有办法生成更优化的查询,同时仍然提供BooleanExpressions的可重用性,还使用Spring Data的存储库?
答案 0 :(得分:1)
可能有更优化的方式,但是不能使用连接,因为它们会修改结果集。因此,如果您找到一种优化Querydsl中any()子查询的方法,那么请在GitHub问题跟踪器中创建一个票证。
当Querydsl用法仅限于谓词时,则无法控制连接。