ネストされたコレクションをSQLやjOOQで実体化する方法はたくさんあります。私はそれらのいくつかを通過しているだけです:
結合の使用
これらのコレクションを深くネストしない場合は、JOIN
を使用して結果を非正規化(フラット化)します。 データが複製されているため、オーバーヘッドをあまり追加せずに、トリックを実行できる可能性があります。基本的に、次のように記述します。
Map<ExperimentRecord, Result<Record>> map =
DSL.using(configuration)
.select()
.from(EXPERIMENT)
.join(TAGS)
.on(...)
.fetchGroups(EXPERIMENT);
上記のマップには、キーとして実験レコードが含まれ、値としてすべてのタグを含むネストされたコレクションが含まれています。
2つのクエリを作成する
複雑なオブジェクトグラフを具体化する場合は、結合の使用が最適ではなくなる可能性があります。代わりに、2つの異なるクエリからクライアントのデータを収集することをお勧めします。
Result<ExperimentRecord> experiments =
DSL.using(configuration)
.selectFrom(EXPERIMENT)
.fetch();
そして
Result<TagsRecord> tags =
DSL.using(configuration)
.selectFrom(TAGS)
.where(... restrict to the previous experiments ...)
.fetch();
そして今、2つの結果をクライアントのメモリにマージします。例:
experiments.stream()
.map(e -> new ExperimentWithTags(
e,
tags.stream()
.filter(t -> e.getId().equals(t.getExperimentId()))
.collect(Collectors.toList())
));
SQL/XMLまたはSQL/JSONを使用したコレクションのネスト
この質問はそれを必要としませんでしたが、他の人はjOOQとの多くの関係をネストする方法を探してこの質問を見つけるかもしれません。 ここに回答を提供しました 。 jOOQ 3.14以降では、RDBMSのSQL/XMLまたはSQL/JSON機能を使用してから、Jackson、Gson、またはJAXBを使用して次のようなコレクションをネストできます。
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);
Experiment
の場所 は次のようなカスタムJavaクラスです:
class Experiment {
long id;
String name;
List<Tag> tags;
}
class Tag {
long id;
String name;
}
MULTISET
を使用したコレクションのネスト
上記よりもさらに優れているのは、 jOOQ3.15の新しいMULTISET
の背後でSQL/XMLまたはSQL/JSONを使用して非表示にすることができます オペレーターサポート
。上記のJavaクラスがJava16レコード(またはその他の不変クラス)であると仮定すると、ネストされたコレクションタイプをDTOに安全にマップすることもできます。
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));
Experiment
の場所 は次のようなカスタムJavaクラスです:
record Experiment(long id, String name, List<Tag> tags) {}
record Tag(long id, String name) {}