jOOQ:在单个对象中返回带有join,groupby和count的列表

时间:2018-04-05 17:30:59

标签: java jooq

核心问题:如何正确地将查询中的信息提取到对象中?


我正在我的DAO中创建函数,它归结为以下查询:

select A.*, count(*)
from A
left join B on B.aId = A.aId
group by A.*

我正在寻找一种方法来创建一个jOOQ表达式,它只给我一个列表(或者我可以循环的东西)和对象A(pojo)和整数。

具体案例
在我的代码案例中:A =志愿者和B = VolunteerMatch,我为每位志愿者存储了几场比赛。 B有(志愿者,志愿者马克)作为小学 键。因此,该查询产生来自志愿者的信息以及匹配的数量。显然,这可以在两个单独的查询中完成,但我想将其作为一个完成!

问题
我找不到在我的函数中返回的单个对象。我想获得像List< VolunteerPojo,Integer>这样的东西。让我用例子解释这个问题,以及为什么它们不适合我。

我尝试了什么1

SelectHavingStep<Record> query = using(configuration())
        .select(Volunteer.VOLUNTEER.fields())
        .select(Volunteermatch.VOLUNTEERMATCH.VOLUNTEERID.count())
        .from(Volunteer.VOLUNTEER)
        .leftJoin(Volunteermatch.VOLUNTEERMATCH).on(Volunteermatch.VOLUNTEERMATCH.VOLUNTEERID.eq(Volunteer.VOLUNTEER.VOLUNTEERID))
        .groupBy(Volunteer.VOLUNTEER.fields());

Map<VolunteerPojo, List<Integer>> map = query.fetchGroups(
                r -> r.into(Volunteer.VOLUNTEER).into(VolunteerPojo.class),
                r -> r.into(Volunteermatch.VOLUNTEERMATCH.VOLUNTEERID.count()).into(Integer.class)
        );

这个问题是我从整数创建一个List。但这不是我想要的,我想要一个整数(计数总是返回一行)。注意:我不希望解决方案“只创建自己没有列表的地图”,因为我的直觉说jOOQ中有一个解决方案。我来这里学习!

我尝试了什么2

SelectHavingStep<Record> query = using(configuration())
        .select(Volunteer.VOLUNTEER.fields())
        .select(Volunteermatch.VOLUNTEERMATCH.VOLUNTEERID.count())
        .from(Volunteer.VOLUNTEER)
        .leftJoin(Volunteermatch.VOLUNTEERMATCH).on(Volunteermatch.VOLUNTEERMATCH.VOLUNTEERID.eq(Volunteer.VOLUNTEER.VOLUNTEERID))
        .groupBy(Volunteer.VOLUNTEER.fields());

Result<Record> result = query.fetch();
for (Record r : result) {
    VolunteerPojo volunteerPojo = r.into(Volunteer.VOLUNTEER).into(VolunteerPojo.class);
    Integer count = r.into(Volunteermatch.VOLUNTEERMATCH.VOLUNTEERID.count()).into(Integer.class);
}

但是,我不想在我的代码中返回结果对象。在我调用此函数的每个地方,我调用r.into(...)。into(...)。在编译期间,如果它返回一个整数或一个真正的pojo,这将不会给出错误。我不希望这样可以防止将来出现错误。但至少它没有把它放在我想的列表中。

推理
这两个选项都可能没问题,但我觉得我在文档中遗漏了一些更好的东西。也许我可以适应(1)不获得整数列表。也许我可以改变结果&lt;记录&gt;结果如Result&lt; VolunteerPojo,Integer&gt;指示实际返回的对象。每个问题的解决方案都很好,因为我越来越多地使用jOOQ,这将是一个很好的学习经历!

1 个答案:

答案 0 :(得分:1)

如此接近!不要使用ResultQuery.fetchGroups()。请改用ResultQuery.fetchMap()

Map<VolunteerPojo, Integer> map =
using(configuration())
    .select(VOLUNTEER.fields())
    .select(VOLUNTEERMATCH.VOLUNTEERID.count())
    .from(VOLUNTEER)
    .leftJoin(VOLUNTEERMATCH)
    .on(VOLUNTEERMATCH.VOLUNTEERID.eq(VOLUNTEER.VOLUNTEERID))
    .groupBy(VOLUNTEER.fields())
    .fetchMap(
         r -> r.into(VOLUNTEER).into(VolunteerPojo.class),
         r -> r.get(VOLUNTEERMATCH.VOLUNTEERID.count())
    );