Querydsl - фильтр левого соединения с подзапросом - PullRequest
0 голосов
/ 05 февраля 2020

У меня один сложный запрос, динамически генерируемый с помощью предиката Querydsl и JPQL. Я также использую классы Q.

Я могу сгенерировать следующий запрос, передав предикат в репозиторий JPA.

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;

Мы используем следующий вид кода, я не могу поделиться точным кодом из-за соображений безопасности, но вы можете помочь мне предоставляя базовую c структуру или код для достижения этой цели.

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;
        }

1 Ответ

0 голосов
/ 05 февраля 2020

Чтобы добавить объединение при двух условиях, используйте

    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 дважды. Фильтрация подзапросов должна быть достаточной. Я подозреваю, что вы можете достичь того же результата без подзапроса. Это зависит от вашей сущности.

...