How to select autogenerated record and additional data with joining in jooq?

Suppose you have two tables, foo

and bar

and the table that matches foo

for the allowed bar

s:

foo             bar
+----+-------+  +----+-------+
| id |fooName|  | id |barName|
+------------+  +----+-------+
| 1  | aa    |  | 10 |  xx   |
| 2  | bb    |  | 11 |  yy   |
| 3  | cc    |  | 12 |  zz   |
+------------+  +----+-------+

      

n: m The ratio between foo

andbar

foo_x_bar
+--------+--------+
| foo_id | bar_id |
+-----------------+
| 1      |  10    |
| 1      |  11    |
| 2      |  11    |
| 3      |  12    |
+-----------------+

      

Now, given any foo.id

(say 1

), I want a list of everyone bar

and whether they are applicable for foo.id

1

. I can do it with this SQL:

SELECT bar.id, bar.barName, foo_x_bar.foo_id 
FROM bar LEFT OUTER JOIN foo_x_bar
ON bar.id = foo_x_bar.bar_id AND foo_x_bar.foo_id = 1;  

      

This gives me the following output:

+--------+-------------+------------------+
| bar.id | bar.barName | foo_x_bar.foo_id |
+--------+-------------+------------------+
|   10   |   xx        |       1          |
|   11   |   yy        |       1          |
|   12   |   zz        |      null        |
+--------+-------------+------------------+

      

Ie: I get the full list bar

and I know what they are referring foo

to id

1

. (All lines with null

for are foo_id

not referenced)

So now (finally) to my question: how to achieve this with jooq, so I BarRecord

end up with nice jooq autogenerates classes for me. This is how I guessed it:

List<Record3<Long, String, Long>> result = 
create.select(BAR.ID, BAR.BARNAME, FOO_X_BAR.FOO_ID)
.from(BAR).leftOuterJoin(FOO_X_BAR)
.on(BAR.ID.eq(FOO_X_BAR.BAR_ID))
.and(FOO_X_BAR.FOO_ID.eq(fooId))
.fetch();

      

This is all well and good, but if it bar

has a lot more columns it gets tedious and I would like to use the autogeneration of the BarRecord

jooq class for me .

How can I get it Record2<BarRecord, Long>

instead?

=============== Edit ==============

Based on the correct answer below, this is the complete code we came across:

public static class BarMapper 
implements RecordMapper<Record, Pair<BarRecord, Boolean>> {
    //the boolean indicates if a matching FOO is present
    return new Pair<BarRecord, Boolean>(
        record.into(BAR), 
        record.getValue(FOO_X_BAR.FOO_ID) != null);
}

public List<Pair<BarRecord, Boolean>> selectBarsForFooId(final long fooId) {
    create.select(BAR.fields()).select(FOO_X_BAR.FOO_ID)
    .from(BAR).leftOuterJoin(FOO_X_BAR)
    .on(BAR.ID.eq(FOO_X_BAR.BAR_ID))
    .and(FOO_X_BAR.FOO_ID.eq(fooId))
    .fetch(new BarMapper());
}

      

+3


source to share


1 answer


You can write:

create.select(BAR.fields())
      .select(FOO_X_BAR.FOO_ID)

      

BAR.fields()

more or less the same as BAR.*

in SQL.

Currently (as of jOOQ 3.4) it is not possible to create nested records in your result via the jOOQ API. This is the pending feature request:



To map (partial) records to a well-typed one BarRecord

, you can simply callRecord.into(Table)

BarRecord bar = Record.into(BAR);

      

+3


source







All Articles