QueryDsl如何实现多字段组合IN查询,匹配自定义参数类集合
问题原因
Expressions.list(cat.pattern, cat.breed).in() 方法要求传入的集合元素与定义的字段列表的类型、顺序完全匹配,直接传入自定义CatParameters对象集合时,QueryDSL无法自动解析类字段与查询字段的对应关系,因此抛出方法不匹配的报错。
解决方法
将List<CatParameters>转换为QueryDSL可识别的字段组合集合即可,两种常用实现方式如下:
方式1:转换为Object数组集合(兼容性最好,写法最简单)
public List<CatDto> getCatsByParameters(List<CatParameters> params) { QCat cat = QCat.cat; // 按查询字段顺序封装为Object数组集合 List<Object[]> paramPairs = params.stream() .map(param -> new Object[]{param.pattern, param.breed}) .toList(); return query.from(cat) .where(Expressions.list(cat.pattern, cat.breed).in(paramPairs)) .list(ConstructorExpression.create(CatDto.class, cat.field1, cat.field2, cat.field3/* 其余需要映射的字段 */)); }
方式2:转换为QueryDSL Tuple集合
import com.querydsl.core.Tuple; import com.querydsl.core.types.dsl.Expressions; public List<CatDto> getCatsByParameters(List<CatParameters> params) { QCat cat = QCat.cat; // 构造Tuple集合 List<Tuple> paramTuples = params.stream() .map(param -> Expressions.tuple( Expressions.constant(param.pattern), Expressions.constant(param.breed) )) .toList(); return query.from(cat) .where(Expressions.list(cat.pattern, cat.breed).in(paramTuples)) .list(ConstructorExpression.create(CatDto.class, cat.field1, cat.field2, cat.field3/* 其余需要映射的字段 */)); }
注意事项
- 转换后的集合元素顺序必须与
Expressions.list()中定义的字段顺序完全一致,字段类型也要匹配,否则会出现查询结果异常或类型转换错误 - 多字段IN语法依赖底层数据库支持,MySQL、PostgreSQL、Oracle等主流关系型数据库均支持该语法
- 如果使用JDK8及以下版本,将stream的
toList()替换为.collect(Collectors.toList())即可
内容的提问来源于stack exchange,提问作者Olegiwe
相关产品推荐
相关产品推荐

