jOOQ: загрузить на карту <K, список <Record2 <V, W >> - PullRequest
0 голосов
/ 05 мая 2018

Абстрактный запрос

select A.*, B.*, C.*
from A
left join B on B.aId = A.aId
left join C on C.cId = B.cId

Идея
Я хочу извлечь это в некоторый объект, который сгруппирован по A (каждый B имеет уникальный C, связанный с ним). Для меня наиболее логичным типом объекта для выборки будет что-то вроде Map >.

код
Я пробовал что-то вроде

using(configuration()).select(A.fields())
        .select(B.fields())
        .select(C.fields())
        .from(A)
        .leftJoin(B).on(B.aId.eq(A.aId)
        .leftJoin(C).on(C.cId.eq(B.cId)
        .fetchGroups(
            r -> r.into(A).into(APojo.class),
            r -> r.into(B).into(BPojo.class),
            r -> r.into(C).into(CPojo.class)); // Goes wrong because fetchGroups only accepts 2 arguments

Фон решения
Я не хочу использовать fetch (), потому что все записи будут содержать дубликаты данных A, которых я хочу избежать. Я преобразую его в объект JSON, где A будет содержать список B и в котором B содержит объект C. Чтобы получить эту структуру, Map > будет идеальным.

1 Ответ

0 голосов
/ 07 мая 2018

Вы должны вручную сгруппировать эти <B, C> типы в некоторую структуру данных, например, jOOλ's Tuple2 тип или также AbstractMap.SimpleEntry

Map<APojo, List<Tuple<BPojo, CPojo>>> result =
using(configuration()).select(A.fields())
        .select(B.fields())
        .select(C.fields())
        .from(A)
        .leftJoin(B).on(B.aId.eq(A.aId))
        .leftJoin(C).on(C.cId.eq(B.cId))
        .fetchGroups(
            r -> r.into(A).into(APojo.class),
            r -> tuple(
                     r.into(B).into(BPojo.class),
                     r.into(C).into(CPojo.class)));

Альтернативой может быть использование потоков и вложенных карт:

Map<APojo, Map<BPojo, CPojo>> result =
using(configuration()).select(A.fields())
        .select(B.fields())
        .select(C.fields())
        .from(A)
        .leftJoin(B).on(B.aId.eq(A.aId))
        .leftJoin(C).on(C.cId.eq(B.cId))
        .fetch()
        .stream()
        .collect(Collectors.groupingBy(
            r -> r.into(A).into(APojo.class),
            Collectors.toMap(
                r -> r.into(B).into(BPojo.class),
                r -> r.into(C).into(CPojo.class))));

jOOQ 3.11 будет включать ResultQuery.collect() метод , поэтому вызов fetchStream() можно опустить:

Map<APojo, Map<BPojo, CPojo>> result =
using(configuration()).select(A.fields())
        .select(B.fields())
        .select(C.fields())
        .from(A)
        .leftJoin(B).on(B.aId.eq(A.aId))
        .leftJoin(C).on(C.cId.eq(B.cId))
        .collect(Collectors.groupingBy(
            r -> r.into(A).into(APojo.class),
            Collectors.toMap(
                r -> r.into(B).into(BPojo.class),
                r -> r.into(C).into(CPojo.class))));
...