【问题标题】:JPA Criteria based query that INTERSECTS three queries at once基于 JPA 标准的查询,一次与三个查询相交
【发布时间】:2020-03-16 16:28:57
【问题描述】:

我想找到所有安装了“b”= 500 和“b”= 501 和“c”= 2 的“a”。

SQL 我会这样做:

select a from table1 where id in (select info_id from table2 where b = '500')
intersect
select a from table1 where id in (select info_id from table2 where b = '501')
intersect
select a from table1 where id in (select info_id from table2 where id in (select ecu_id from table3        where c = '2'));

所以我会创建三个SQL 查询,然后取这三个查询的交集。 但我现在必须使用基于 JPA criteria 的查询,而不是原生的 SQLJPQL

我们可以执行三个不同的基于JPA criteria 的查询:

返回一个“a”列表,其中“b”= 500,

返回一个“a”列表,其中“b”= 501 和

返回一个“a”列表,其中“c”=2。

然后过滤所有三个返回列表中出现的所有“a”。但这会花费太长时间,我们的数据库包含数百万个“a”条目......

【问题讨论】:

标签: java sql jpa


【解决方案1】:

所以这是 SQL 中的一种解决方案: http://tpcg.io/mV3rZ2Of

这是一个很长的 JPA Criteria Query,所以我只展示我如何翻译最后一个 Exists 条件,这是最难的部分:

Subquery<Table3> subQuery = searchQuery.subquery(Table3.class);
Root<Table3> fromTable3SubQuery = subQuery.from(Table3.class);
List<Predicate> subRestrictions = new ArrayList<>();

Subquery<Table2> subQueryForInExpression = searchQuery.subquery(Table2.class);
Root<Table2> fromTable2SubQuery = subQueryForInExpression.from(Table2.class);
subQueryForInExpression.select(fromTable2SubQuery.get(ID)).where(criteriaBuilder.equal(fromTable2SubQuery.get(info_id), root.get(ID)));

subRestrictions.add(criteriaBuilder.equal(fromTable3SubQuery.get(c), '2'));
subRestrictions.add(criteriaBuilder.in(fromTable3SubQuery.get(ecu_id)).value(subQueryForInExpression));

restrictions.add(criteriaBuilder.exists(subQuery.select(
                    fromTable3SubQuery.get(c)).where(
                            subRestrictions.toArray(new Predicate[0]))));

-> 这仅代表最后一个Existspart,它要求c = '2' 连接。其他类似,但没有subQueryForInExpression 部分...

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-11-12
  • 2012-04-01
  • 2016-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
相关资源
最近更新 更多