jpa Query dsl -循环遍历列表以创建OR predicate

3lxsmp7m  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(261)

如果我使用List<List<String>>查询dsl和spring数据,如何动态创建“OR” predicate ?

QOrder order = QOrder.order;
JPQLQuery<Order> query = from(order);
query.where(order.status.eq("ready"));
List<List<String>> filterTypes;

这就是我正在努力做的:

for(List<String> types : filterTypes) {
    query.where(order.type.in(types));
}

所以结果应该是

select * from order o where o.status='ready' and (o.type in(t1,t2) or o.type in(t3,t4))
db2dz4w8

db2dz4w81#

直接回答您的问题:假设您使用的是相对较新的QueryDSL版本,那么您应该能够使用BooleanBuilder

QOrder order = QOrder.order;
SQLQuery<Order> query = from(order);
query.where(order.status.eq("ready"));
// Example data
List<List<String>> filterTypes = ImmutableList.of(
        ImmutableList.of("t1", "t2"),
        ImmutableList.of("t3", "t4"));

BooleanBuilder builder = new BooleanBuilder();

for (List<String> types : filterTypes) {
    builder.or(order.type.in(types));
}

query.where(builder);

备份,假设您的实际应用程序数据模型与您提供的示例类似,这:

o.type in (t1,t2) or o.type in (t3,t4)

相当于:

o.type in (t1,t2,t3,t4)

您可以将List<List<String>>转换为List<String>,然后执行一次类型查询更新:

QOrder order = QOrder.order;
SQLQuery<Order> query = from(order);
query.where(order.status.eq("ready"));
// Example data
List<List<String>> filterTypes = ImmutableList.of(
        ImmutableList.of("t1", "t2"),
        ImmutableList.of("t3", "t4"));
List<String> flatFilterTypes = filterTypes.stream().flatMap(List::stream).collect(Collectors.toList());
query.where(order.type.in(flatFilterTypes));

我 * 怀疑 * 您的数据库的查询优化器会对这两个查询做同样的事情(您必须检查query execution plan to be sure),但是如果您在Java端简化查询而不是依赖数据库查询优化器,可能会更清楚地看到发生了什么。

相关问题