JAVA Querydsl 4.1.4 сложный запрос, setPath любой с несколькими фильтрами - PullRequest
0 голосов
/ 09 января 2019

Я использую базу данных JPA HIBERNATE H2 для своего проекта.

В настоящее время я пытаюсь создать предикат с необязательными частичными предикатами, все работало нормально, пока мне не пришлось создавать сложные запросы.

Я бы хотел отфильтровать мои продукты по тем, у которых есть компонент композиции, чье количество по умолчанию меньше его максимального количества

Я написал такую ​​функцию:

private BooleanExpression getBooleanPredicateComposition(ListPath<Product.Composition.Component, QProduct_Composition_Component> component, QProduct_Composition_Component qpath, Boolean params) {
        if(null == params) {
            return null;
        }
        BooleanExpression be = qpath.defaultQuantity.lt(qpath.maxQuantity);
        return (params ? be : component.size().gt(0).not());
    }

В результате этого выполняется следующий sql:

select
                    1 
                from
                    product$composition product_co3_ 
                inner join
                    product$composition_component component4_ 
                        on product_co3_.composition_id=component4_.product$composition_composition_id

                inner join
                    product$composition_component component5_ 
                        on product_co3_.composition_id=component5_.product$composition_composition_id

                where
                    product_co3_.composition_id=product0_.composition_composition_id 
                    and product_co3_.composition_id=product0_.composition_composition_id 
                    and component4_.default_quantity<component5_.max_quantity

Но я хочу sql, где component4_default_quantity связан со своим собственным max_quantity, а не с другой объединенной таблицей, как в настоящее время.

Я точно не эксперт по SQL, на самом деле у меня очень мало опыта с этим, но я думаю, что это должно быть примерно так:

select
                    1 
                from
                    product$composition product_co3_ 
                inner join
                    product$composition_component component4_ 
                        on product_co3_.composition_id=component4_.product$composition_composition_id 
                where
                    product_co3_.composition_id=product0_.composition_composition_id 
                    and product_co3_.composition_id=product0_.composition_composition_id 
                    and component4_.default_quantity<component4_.max_quantity

Так как мне его кодировать?

Я испробовал много разных техник, таких как создание нового JPAExpression или обращение к базовому классу QProduct_Composition_Component.component, но ни один из них, похоже, не работает для меня ..

Заранее спасибо!

Обновление:

Остальной код, откуда я вызываю эту функцию

 public Predicate getPredicate(ComplexProduct complexProduct) {
        return new BooleanBuilder()
                .and(PRODUCT.country.eq(complexProduct.getCountry()))
                .and(PRODUCT.storeId.eq(complexProduct.getStore()))
                .and(getPartialPredicate(complexProduct).build());
    }

    private WhereClauseBuilder getPartialPredicate(ComplexProduct complexProduct) {
        WhereClauseBuilder whereClauseBuilder = new WhereClauseBuilder()
                .optionalAnd(PRODUCT.onOutage::eq,complexProduct.getOnOutage())
                .optionalAnd(getBooleanPredicateZeroPriced(PRODUCT.priceList.priceTag.pricing.any().price,complexProduct.getZeroPriced(), complexProduct.getNullPriceAllowed()))
                .optionalAnd(getBooleanPredicateSalable(PRODUCT.salable, complexProduct.getSalable()))
                .optionalAnd(getBooleanPredicateIsActive(PRODUCT.isActive, complexProduct.getIsActive()))
                .optionalAnd(getBooleanPredicateHasPromotionTimeRestriction(PRODUCT.promotion.timeRestrictions, complexProduct.getHasPromotionTimeRestriction()))
                .optionalAnd(getBooleanPredicateString(PRODUCT.grillGroup, complexProduct.getGrillGroup()))
                .optionalAnd(getBooleanPredicateExistsAndHasElement(PRODUCT.canAdds.component, complexProduct.getGrilledCanAdd()))
                .optionalAnd(getBooleanPredicateExistsAndHasElement(PRODUCT.comments.component, complexProduct.getGrilledComment()))
                .optionalAnd(getBooleanPredicateExistsAndHasElement(PRODUCT.choices.component, complexProduct.getGrilledChoice()))
                .optionalAnd(getBooleanPredicateComposition(PRODUCT.composition.component, PRODUCT.composition.component.any(), complexProduct.getCompositionNeeded()))
                .optionalAnd(getBooleanPredicateAvailability(PRODUCT, complexProduct.getTime(), complexProduct.getTime(), complexProduct.getDayName(), complexProduct.getAvailableAt()))
                .optionalAnd(getBooleanPredicateCustomParameter(PRODUCT.customParameters, "nutritionalInfoEnergy",complexProduct.getNutritionalInfoEnergy()));
        if(complexProduct.getDistributions() != null) {
            addDistributionFilters(whereClauseBuilder, complexProduct.getDistributions().stream().map(distribution -> distribution.name()).collect(Collectors.toList()));
        }
        WhereClauseBuilder partialWhere = null;
        if(complexProduct.getType() != null) {
            if(complexProduct.getType() != null) {
                if (partialWhere == null) {
                    partialWhere = new WhereClauseBuilder();
                }
                partialWhere = partialWhere.optionalOr(PRODUCT.productClass::eq,  complexProduct.getType().getName());
            }
        }
        if(partialWhere != null) {
            whereClauseBuilder.optionalAnd(partialWhere.build());
        }

        return whereClauseBuilder;
    }
...