Можно ли сделать оператор where в операторе с подзапросом с группой по той же таблице, используя JpaSpecificationExecutor? - PullRequest
0 голосов
/ 18 октября 2019

Я использую репозиторий Spring Data JpaSpecificationExecutor. Я могу сделать динамический оператор where с помощью спецификации метода findAll JapSpecificationExecutor.

текущий код и схема таблицы в таком виде

History Table

id |сообщение |groupId

1 'text' 1

2 'cotent' 1

3 'ttt' 2

4 'rrr' 3

historyRepository
                         .findAll(
                                 where(
                                         /** common */
                                         sndId(sndUId))
                                         .and(kind(kind))
                                         .and(sndIdNotNull())
                                         .and(groupTokenNotNull())
                                         /** search option */
                                         .and(searchHistory(historyRequestDto))
                                 /** order by date */
                                 , new PageRequest(0, 50, new Sort(Sort.Direction.DESC, "sndDate"))
                         )

Я хочу, чтобы мой код генерировал собственный запрос MySQL как этот

select * from History 
where
    id IN (
        select 
            min(id) 
        from 
            History 
        where
            kind = 4 
            and kind is not null
            and sndId is not null
            and groupToken is not null
        group by (groupToken) 
) order by sndDate desc
limit 0, 10    

Могу ли я генерировать такой код?

1 Ответ

0 голосов
/ 18 октября 2019

Да, это должно быть возможно.

Метод findAll ожидает Specification, который в основном является функцией от

Root, CriteriaQuery, CriteriaBuilder до Predicate

https://thoughts -on-java.org / hibernate-tip-subquery-attributequery / описывает, как создать условие x in (subquery):

что-то вродеэто должно сработать:

(Root root, CriteriaQuery cq, CriteriaBuilder cb) -> {
    Subquery sub = cq.subquery(Long.class);
    Root subRoot = sub.from(History.class);
    sub.select(cb.min(subRoot.get("id")));
    sub.where(/* insert your existing conditions here */);

    // check the result of the subquery
    return cb.in(sub);
}

Я на самом деле не пробовал, так что, безусловно, потребуется некоторая настройка, но общая идея должна работать.

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