Ada banyak cara untuk mewujudkan koleksi bersarang dengan SQL, dan / atau dengan jOOQ. Saya hanya membahas beberapa di antaranya:
Menggunakan gabungan
Jika Anda tidak mengumpulkan koleksi tersebut secara mendalam, denormalisasi (meratakan) hasil Anda dengan JOIN
mungkin melakukan trik untuk Anda, tanpa menambahkan terlalu banyak overhead karena data sedang diduplikasi. Intinya, Anda akan menulis:
Map<ExperimentRecord, Result<Record>> map =
DSL.using(configuration)
.select()
.from(EXPERIMENT)
.join(TAGS)
.on(...)
.fetchGroups(EXPERIMENT);
Peta di atas berisi catatan eksperimen sebagai kunci, dan kumpulan bersarang yang berisi semua tag sebagai nilai.
Membuat dua kueri
Jika Anda ingin mewujudkan grafik objek yang kompleks, menggunakan gabungan mungkin tidak lagi optimal. Sebagai gantinya, Anda mungkin ingin mengumpulkan data di klien Anda dari dua kueri berbeda:
Result<ExperimentRecord> experiments =
DSL.using(configuration)
.selectFrom(EXPERIMENT)
.fetch();
Dan
Result<TagsRecord> tags =
DSL.using(configuration)
.selectFrom(TAGS)
.where(... restrict to the previous experiments ...)
.fetch();
Dan sekarang, gabungkan kedua hasil di memori klien Anda, mis.
experiments.stream()
.map(e -> new ExperimentWithTags(
e,
tags.stream()
.filter(t -> e.getId().equals(t.getExperimentId()))
.collect(Collectors.toList())
));
Mengumpulkan koleksi menggunakan SQL/XML atau SQL/JSON
Pertanyaan ini tidak memerlukannya, tetapi orang lain mungkin menemukan pertanyaan ini dalam mencari cara untuk menghubungkan ke banyak hubungan dengan jOOQ. Saya sudah memberikan jawaban di sini . Dimulai dengan jOOQ 3.14, Anda dapat menggunakan kemampuan SQL/XML atau SQL/JSON RDBMS, lalu menggunakan Jackson, Gson, atau JAXB untuk mengumpulkan koleksi seperti ini:
List<Experiment> experiments =
ctx.select(
EXPERIMENT.asterisk(),
field(
select(jsonArrayAgg(jsonObject(TAGS.fields())))
.from(TAGS)
.where(TAGS.EXPERIMENT_ID.eq(EXPERIMENT.ID))
).as("tags")
)
.from(EXPERIMENT)
.fetchInto(Experiment.class);
Dimana Experiment
adalah kelas Java khusus seperti ini:
class Experiment {
long id;
String name;
List<Tag> tags;
}
class Tag {
long id;
String name;
}
Mengumpulkan koleksi menggunakan MULTISET
Bahkan lebih baik dari yang di atas, anda dapat bersembunyi menggunakan SQL/XML atau SQL/JSON di belakang MULTISET
baru jOOQ 3.15 dukungan operator
. Dengan asumsi kelas Java di atas adalah catatan Java 16 (atau kelas abadi lainnya), Anda bahkan dapat memetakan jenis koleksi bersarang dengan aman ke dalam DTO Anda:
List<Experiment> experiments =
ctx.select(
EXPERIMENT.ID,
EXPERIMENT.NAME,
multiset(
select(TAGS.ID, TAGS.NAME)
.from(TAGS)
.where(TAGS.EXPERIMENT_ID.eq(EXPERIMENT.ID))
).as("tags").convertFrom(r -> r.map(Records.mapping(Tag::new)))
)
.from(EXPERIMENT)
.fetch(Records.mapping(Experiment::new));
Dimana Experiment
adalah kelas Java khusus seperti ini:
record Experiment(long id, String name, List<Tag> tags) {}
record Tag(long id, String name) {}
Lihat juga posting blog ini untuk informasi lebih lanjut .