Запрос, основанный на критериях JPA, который ИНТЕРЕСУЕТ три запроса одновременно - PullRequest
0 голосов
/ 16 марта 2020

Я хочу найти все "a", у которых "b" = 500 и "b" = 501 и "c" = 2. my three tables

В 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 запроса и затем взял бы пересечение эти 3. Но теперь я должен использовать запросы на основе JPA criteria, а не нативные SQL или JPQL.

Мы могли бы выполнить три отдельных запроса на основе JPA criteria:

, которые возвращает список «a», где «b» = 500,

, который возвращает список «a», где «b» = 501, и

, который возвращает список «a» "where" c "= 2.

А затем отфильтруйте все« a », которые появляются во всех трех возвращенных списках. Но это заняло бы слишком много времени, наша база данных содержит много миллионов записей "a" ...

1 Ответ

0 голосов
/ 19 марта 2020

Так что это одно из решений в SQL: http://tpcg.io/mV3rZ2Of

Это очень длинный запрос JPA Criteria, поэтому я показываю только, как я перевел последний 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]))));

-> Это представляет только последнюю часть Exists, которая запрашивает соединение c = '2'. Другие похожи, но без subQueryForInExpression частей ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...