java 列表中的QueryDsl元组< Tuple>

ffscu2ro  于 2023-02-18  发布在  Java
关注(0)|答案(1)|浏览(243)

假设我有一个包含很多列的猫的表,我尝试在QueryDsl中执行以下查询:

select * from cat where (cat.pattern, cat.breed) in (('calico', 'Siberian'), ('grey', 'Siamese'), ('tabby', 'Maine Coon'));

在Java中,我有一个类来参数化我的猫:

class CatParameters {
    public String pattern;
    public String breed;
}

和这个方法(不幸的是不正确的)从数据库中获取猫:

public List<CatDto> getCatsByParameters(List<CatParameters> params) {
// something like this
QCat cat = QCat.cat;
return query.from(cat)
    .where(Expressions.list(cat.pattern, cat.breed).in(params))
    .list(ConstructorExpression.create(CatDto.class, cat.field1, cat.field2, cat.field3, .../* etc */))
}

这显然会导致错误"Cannot resolve method 'in(java.util.List<my.package.name.Cat>)'"
那么,我如何查询具有这些属性的java对象列表中的(colX,colY)的猫呢?
UPD:我发现this question在相当相似的主题上使用子查询而不是集合,但我想知道是否有一种方法可以使用集合(或者可能以某种方式从列表创建列表)。

jtoj6r0c

jtoj6r0c1#

对于the maintainers of QueryDSL,使用CollectionExpression或嵌套的Expression.list都不是正确的方法,相反,需要使用Template表达式(正如在这个问题的注解中所暗示的)。

public List<CatDto> getCatsByParameters(List<CatParameters> params) {
    QCat cat = QCat.cat;
    return query.from(cat)
            .where(Expressions.list(cat.pattern, cat.breed).in(Expressions.list(
                    params.stream()
                            .map(catParam -> makeTuple(
                                Expressions.constant(catParam.pattern), Expressions.constant(catParam.breed)))
                            .toArray(new Expression[0])
            )))
            .list(ConstructorExpression.create(CatDto.class, cat.field1, cat.field2, cat.field3, .../* etc */))
}

private static SimpleExpression<Object> makeTuple(Expression<?>... args) {
    return Expressions.template(Object.class, "({0}, {1})", (Object[]) args);
}

相关问题