jOOQ: returning list with join,groupby and count in single object

我与影子孤独终老i 提交于 2019-12-11 04:26:15

问题


Core question: how do you properly fetch information from a query into objects?

Idea
I am creating functions in my DAO, which comes down to the following query:

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

Im looking for a way to create a jOOQ expression that just gives me a list (or something I can loop over) with objects A (pojo) and Integer.

Concrete case
In my code case: A = Volunteer and B = VolunteerMatch where I store several matches for each volunteer. B has (volunteerId, volunteerMatchId) as primary key. Thus this query results in both the information from the Volunteer, as well as the number of matches. Clearly this can be done in two seperate queries, but I want to do it as one!

Problem
I cannot find a single object to return in my function. I am trying to get something like List<VolunteerPojo, Integer>. Let me explain this better using examples and why they dont fit for me.

What I tried 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)
        );

The problem with this, is that I create a List from the integers. But that is not what I want, I want a single integer (the count will always return one row). Note: I don't want the solution "just create your own map without list", since my gut says there is a solution inside jOOQ. Im here to learn!

What I tried 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);
}

However, I do not want to return the result object in my code. On each place I call this function, I am calling the r.into(...).into(...). During compile time, this won't give an error if it returns an integer or a real pojo. I don't want this to prevent future errors. But at least it doesn't give it in a List I suppose.

Reasoning
Either option is probably fine, but I have the feeling there is something better that I missed in the documentation. Maybe I can adapt (1) to not get a list of integers. Maybe I can change Result<Record> into something like Result<VolunteerPojo, Integer> to indicate what objects really are returned. A solution for each problem would be nice, since I am using jOOQ more and more and this would be a good learning experience!


回答1:


So close! Don't use ResultQuery.fetchGroups(). Use ResultQuery.fetchMap() instead:

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())
    );


来源:https://stackoverflow.com/questions/49678222/jooq-returning-list-with-join-groupby-and-count-in-single-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!