JOOQ:如何使用多重集
JOOQ: how to use multiset
鉴于这 3 个表具有多对多关系
本书
book_id
title
isbn
num_pages
1
JOOQ
1234
123
2
SQL
2345
155
book_author
book_id
author_id
1
1
2
1
2
2
作者
author_id
author_name
1
Lucas
2
Jose
并记录
public record Book(Integer id, String title, String isbn, List<Author> authors) {}// don't need nr of pages
public record Author(Integer id, String name){}
如何使用多重集获得 List<Book>
?
List<Book> books = dsl.select(
BOOK_AUTHOR.BOOK_ID,
select(BOOK.TITLE).from(BOOK).where(BOOK.BOOK_ID.eq(BOOK_AUTHOR.BOOK_ID)).asField("title"),
select(BOOK.ISBN).from(BOOK).where(BOOK.BOOK_ID.eq(BOOK_AUTHOR.BOOK_ID)).asField("isbn"),
multiset(
selectFrom(AUTHOR).where(AUTHOR.AUTHOR_ID.eq(BOOK_AUTHOR.AUTHOR_ID))
).as("authors").convertFrom(record -> record.map(Records.mapping(Author::new)))
).from(BOOK_AUTHOR)
.where(BOOK_AUTHOR.BOOK_ID.in(1, 2))
.fetchInto(Book.class);
books.forEach(System.out::println);
预期包含 2 本书的列表,但得到的是 3 本书!?...
Book{id=1, title='JOOQ', isbn='1234', authors=[Author{name='Lucas'}]}
Book{id=2, title='SQL', isbn='2345', authors=[Author{name='Lucas'}]}
Book{id=2, title='SQL', isbn='2345', authors=[Author{name='Jose'}]}
有什么问题?
生成的SQL:
select "public"."book_author"."book_id", (select "public"."book"."title" from "public"."book" where "public"."book"."book_id" = "public"."book_author"."book_id") as "title", (select "public"."book"."isbn" from "public"."book" where "public"."book"."book_id" = "public"."book_author"."book_id") as "isbn", (select coalesce(jsonb_agg(jsonb_build_array("v0", "v1")), jsonb_build_array()) from (select "public"."author"."author_id" as "v0", "public"."author"."author_name" as "v1" from "public"."author" where "public"."author"."author_id" = "public"."book_author"."author_id") as "t") as "authors" from "public"."book_author" where "public"."book_author"."book_id" in (1, 2)
已用:
- JAVA 17
- POSTGRESQL
- spring-boot (2.6.1) 与 spring-boot-starter-jooq
- JOOQ 3.15.4(允许使用
multiset
函数)
- JOOQ代码生成(maven插件)
问题是您从具有 3 个条目的 BOOK_AUTHOR 开始。你应该 select 来自 BOOK:
List<Book> books = dsl.select(
BOOK.BOOK_ID,
BOOK.TITLE,
BOOK.ISBN,
multiset(
select(AUTHOR.AUTHOR_ID,AUTHOR.AUTHOR_NAME)
.from(AUTHOR).innerJoin(BOOK_AUTHOR)
.on(BOOK_AUTHOR.AUTHOR_ID.eq(AUTHOR.AUTHOR_ID))
.where(BOOK_AUTHOR.BOOK_ID.eq(BOOK.BOOK_ID))
).as("authors")
.convertFrom(record -> record.map(Records.mapping(Author::new)))
).from(BOOK)
.where(BOOK.BOOK_ID.in(1, 2))
.fetchInto(Book.class);
鉴于这 3 个表具有多对多关系
本书
book_id | title | isbn | num_pages |
---|---|---|---|
1 | JOOQ | 1234 | 123 |
2 | SQL | 2345 | 155 |
book_author
book_id | author_id |
---|---|
1 | 1 |
2 | 1 |
2 | 2 |
作者
author_id | author_name |
---|---|
1 | Lucas |
2 | Jose |
并记录
public record Book(Integer id, String title, String isbn, List<Author> authors) {}// don't need nr of pages
public record Author(Integer id, String name){}
如何使用多重集获得 List<Book>
?
List<Book> books = dsl.select(
BOOK_AUTHOR.BOOK_ID,
select(BOOK.TITLE).from(BOOK).where(BOOK.BOOK_ID.eq(BOOK_AUTHOR.BOOK_ID)).asField("title"),
select(BOOK.ISBN).from(BOOK).where(BOOK.BOOK_ID.eq(BOOK_AUTHOR.BOOK_ID)).asField("isbn"),
multiset(
selectFrom(AUTHOR).where(AUTHOR.AUTHOR_ID.eq(BOOK_AUTHOR.AUTHOR_ID))
).as("authors").convertFrom(record -> record.map(Records.mapping(Author::new)))
).from(BOOK_AUTHOR)
.where(BOOK_AUTHOR.BOOK_ID.in(1, 2))
.fetchInto(Book.class);
books.forEach(System.out::println);
预期包含 2 本书的列表,但得到的是 3 本书!?...
Book{id=1, title='JOOQ', isbn='1234', authors=[Author{name='Lucas'}]}
Book{id=2, title='SQL', isbn='2345', authors=[Author{name='Lucas'}]}
Book{id=2, title='SQL', isbn='2345', authors=[Author{name='Jose'}]}
有什么问题?
生成的SQL:
select "public"."book_author"."book_id", (select "public"."book"."title" from "public"."book" where "public"."book"."book_id" = "public"."book_author"."book_id") as "title", (select "public"."book"."isbn" from "public"."book" where "public"."book"."book_id" = "public"."book_author"."book_id") as "isbn", (select coalesce(jsonb_agg(jsonb_build_array("v0", "v1")), jsonb_build_array()) from (select "public"."author"."author_id" as "v0", "public"."author"."author_name" as "v1" from "public"."author" where "public"."author"."author_id" = "public"."book_author"."author_id") as "t") as "authors" from "public"."book_author" where "public"."book_author"."book_id" in (1, 2)
已用:
- JAVA 17
- POSTGRESQL
- spring-boot (2.6.1) 与 spring-boot-starter-jooq
- JOOQ 3.15.4(允许使用
multiset
函数) - JOOQ代码生成(maven插件)
问题是您从具有 3 个条目的 BOOK_AUTHOR 开始。你应该 select 来自 BOOK:
List<Book> books = dsl.select(
BOOK.BOOK_ID,
BOOK.TITLE,
BOOK.ISBN,
multiset(
select(AUTHOR.AUTHOR_ID,AUTHOR.AUTHOR_NAME)
.from(AUTHOR).innerJoin(BOOK_AUTHOR)
.on(BOOK_AUTHOR.AUTHOR_ID.eq(AUTHOR.AUTHOR_ID))
.where(BOOK_AUTHOR.BOOK_ID.eq(BOOK.BOOK_ID))
).as("authors")
.convertFrom(record -> record.map(Records.mapping(Author::new)))
).from(BOOK)
.where(BOOK.BOOK_ID.in(1, 2))
.fetchInto(Book.class);