Querydsl-使用子查询在左联接上进行过滤

时间:2020-02-05 08:11:54

标签: spring-boot jpa java-8 querydsl type-safety

我有一个通过Querydsl谓词和JPQL动态生成的复杂查询之一。我也在使用Q类。

我可以通过将谓词传递到JPA存储库来生成以下查询。

@OnClick(R.id.btnCourseType)
fun btnCourseTypeClick(){
    val fm = activity!!.supportFragmentManager
    val courseTypeListDialogFragment =
        CourseTypeListDialogFragment()
    courseTypeListDialogFragment.setCancelable(false)
    courseTypeListDialogFragment.setStyle(
        DialogFragment.STYLE_NO_TITLE,
        0
    )
    courseTypeListDialogFragment.setTargetFragment(this@CoursesFragment, 1)
    courseTypeListDialogFragment.show(fm, "")

}

但是我想要下面提到的查询

select company0_.id as id1_18_,
   company0_.name as name2_18_
from company company0_
left outer join companyAddress companyadd1_ on company0_.id=companyadd1_.company_id
where company0_.id in
    (select companyadd2_.company_id
     from companyAddress companyadd2_
     where companyadd2_.address_type='1')
order by companyadd1_.addressline1;

我们正在使用以下类型的代码,出于安全考虑,我可能无法共享确切的代码,但是您可以通过提供基本结构或代码来帮助我。

select company0_.id as id1_18_,
   company0_.name as name2_18_
from company company0_
left outer join companyAddress companyadd1_ on company0_.id=companyadd1_.company_id
and companyadd1_.status = 'Active' -- New added(Failed to implement this)
where company0_.id in
    (select companyadd2_.company_id
     from companyAddress companyadd2_
     where companyadd2_.address_type='1'
     and and companyadd2_.status = 'Active') -- New Added(I am able to achieve this)
order by companyadd1_.addressline1;

1 个答案:

答案 0 :(得分:0)

要在两个条件下添加联接,请使用

    new JPAQuery(em)
        .from(qCompany)
        .leftJoin(qCompany, qCompanyAddress.company)       
        .on(
            qCompany.id.eq(qCompanyAddress.company.id)
            .and(qCompanyAddress.status.eq(status))
        );

对于子查询,请尝试使用此

final JPQLQuery<QCompanyAlias> subQuery = new JPAQuery<>();
        BooleanExpression exp = null;
        QueryBase<?> q = (QueryBase<?>) subQuery.from(qCompanyAddress);
        if (requestMap.containsKey(CompanyQueryConstants.ADDRESS_TYPE)) {
            BooleanExpression addrExp = null;
            for (String addressType : addressTypes) {
                if (addrExp == null) {
                    addrExp = qCompanyAddress.addressType.addressTypeCode.eq(addressType);
                } else {
                    addrExp = addrExp.or(qCompanyAddress.addressType.addressTypeCode.eq(addressType));
                }
            }
            exp = addrExp;
        }

        BooleanExpression statusExp = qCompanyAddress.status.eq(status);

        if(exp == null) {
            exp = statusExp;
        } else {
            exp = statusExp.and(exp);
        }

但是对于您而言,我无法理解两次被status过滤的原因。子查询过滤应该足够了。我怀疑无需子查询就可以达到相同的结果。这取决于您的实体。