I'm trying to write a query in which I fetch child records for my aggregate root using leftJoin
like this:
dslContext.select()
.from(PARENT)
.leftJoin(CHILD)
.on(CHILD.PARENT_ID.eq(PARENT.ID))
.stream()
My problem is that I need to use stream
because there are a very big number of records but this way I can't use fetchGroups
which I would normally use when I need parent-child records.
This is how I'd use fetchGroups
:
dslContext.select()
.from(PARENT)
.leftJoin(CHILD)
.on(CHILD.PARENT_ID.eq(PARENT.ID))
.fetchGroups(Parent.class, Child.class)
which would create a nice Map<Parent, Child>
for me.
I tried to collect
using Collectors.groupingBy
but it is not straightforward how to use it and the docs don't explain it either.
How can I fetch parent-child records in one go lazily?
Just to name a few, here are some of jOOQ's fetching modes: Untyped vs. typed fetching: Sometimes you care about the returned type of your records, sometimes (with arbitrary projections) you don't.
If your result sets are large, or if you have a lot of network latency, you may wish to fetch records one-by-one, or in small chunks. jOOQ supports a org.jooq.Cursor type for that purpose. In order to obtain such a reference, use the ResultQuery.fetchLazy () method. An example is given here:
Fetching data reactively: In a reactive programming model, you will want to fetch results from a publisher into a subscription. jOOQ implements different Publisher APIs. The term "fetch" is always reused in jOOQ when you can fetch data from the database. An org.jooq.ResultQuery provides many overloaded means of fetching data:
1. Introduction In this tutorial, we're going to take a quick tour of running an application with jOOQ (Java Object Orientated Query). This library generates Java classes based on the database tables and lets us create type-safe SQL queries through its fluent API.
In jOOQ 3.11, we have added a new ResultQuery.collect()
method, and we are planning on re-implementing most of our fetchXYZ()
logic as standard Collector
implementations, which can then be used with Stream
to achieve exactly what you're looking for. The main driver for this is to avoid the proliferation of more of these fetchXYZ()
overloads, and to offer more composability.
You can do it manually, of course:
Stream
, in case you want to add additional operations to the stream pipeline// Don't forget, this is a resourceful stream!
try (Stream<Record> stream = dslContext.select()
.from(PARENT)
.leftJoin(CHILD)
.on(CHILD.PARENT_ID.eq(PARENT.ID))
.stream()) {
Map<Parent, List<Child>> result = stream.collect(
Collectors.groupingBy(r -> r.into(Parent.class),
Collectors.mapping(r -> r.into(Child.class), Collectors.toList())
)
);
}
The Javadoc of Collectors.groupingBy()
has a similar example.
ResultQuery.collect()
, if you don't need the stream pipeline.Alternatively, using jOOQ 3.11's ResultQuery.collect()
Map<Parent, List<Child>> result = dslContext
.select()
.from(PARENT)
.leftJoin(CHILD)
.on(CHILD.PARENT_ID.eq(PARENT.ID))
.collect(
Collectors.groupingBy(r -> r.into(Parent.class),
Collectors.mapping(r -> r.into(Child.class), Collectors.toList())
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With