Có nhiều cách để hiện thực hóa một tập hợp lồng nhau với SQL và / hoặc với jOOQ. Tôi chỉ xem qua một số trong số đó:
Sử dụng liên kết
Nếu bạn không lồng sâu các bộ sưu tập đó, hãy khử chuẩn hóa (làm phẳng) kết quả của bạn bằng JOIN
có thể thực hiện thủ thuật cho bạn mà không cần thêm quá nhiều chi phí vì dữ liệu đang bị trùng lặp. Về cơ bản, bạn sẽ viết:
Map<ExperimentRecord, Result<Record>> map =
DSL.using(configuration)
.select()
.from(EXPERIMENT)
.join(TAGS)
.on(...)
.fetchGroups(EXPERIMENT);
Bản đồ trên chứa các bản ghi thử nghiệm dưới dạng khóa và các bộ sưu tập lồng nhau chứa tất cả các thẻ dưới dạng giá trị.
Tạo hai truy vấn
Nếu bạn muốn hiện thực hóa một biểu đồ đối tượng phức tạp, việc sử dụng các phép nối có thể không còn là tối ưu nữa. Thay vào đó, bạn có thể muốn thu thập dữ liệu trong khách hàng của mình từ hai truy vấn riêng biệt:
Result<ExperimentRecord> experiments =
DSL.using(configuration)
.selectFrom(EXPERIMENT)
.fetch();
Và
Result<TagsRecord> tags =
DSL.using(configuration)
.selectFrom(TAGS)
.where(... restrict to the previous experiments ...)
.fetch();
Và bây giờ, hãy hợp nhất hai kết quả trong bộ nhớ của khách hàng của bạn, ví dụ:
experiments.stream()
.map(e -> new ExperimentWithTags(
e,
tags.stream()
.filter(t -> e.getId().equals(t.getExperimentId()))
.collect(Collectors.toList())
));
Lồng bộ sưu tập bằng SQL / XML hoặc SQL / JSON
Câu hỏi này không yêu cầu, nhưng những người khác có thể tìm thấy câu hỏi này để tìm kiếm cách lồng vào nhiều mối quan hệ với jOOQ. Tôi đã cung cấp câu trả lời ở đây . Bắt đầu với jOOQ 3.14, bạn có thể sử dụng các khả năng SQL / XML hoặc SQL / JSON của RDBMS và sau đó sử dụng Jackson, Gson hoặc JAXB để lồng các bộ sưu tập như sau:
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);
Nơi Experiment
là một lớp Java tùy chỉnh như thế này:
class Experiment {
long id;
String name;
List<Tag> tags;
}
class Tag {
long id;
String name;
}
Lồng bộ sưu tập bằng MULTISET
Thậm chí còn tốt hơn phần trên, bạn có thể ẩn bằng cách sử dụng SQL / XML hoặc SQL / JSON đằng sau MULTISET
mới của jOOQ 3.15 hỗ trợ nhà điều hành
. Giả sử các lớp Java ở trên là các bản ghi Java 16 (hoặc bất kỳ lớp bất biến nào khác), bạn thậm chí có thể ánh xạ loại bộ sưu tập lồng nhau một cách an toàn vào DTO của mình:
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));
Nơi Experiment
là một lớp Java tùy chỉnh như thế này:
record Experiment(long id, String name, List<Tag> tags) {}
record Tag(long id, String name) {}
Xem thêm bài đăng trên blog này để biết thêm thông tin .