sql >> Database teknologi >  >> RDS >> Mysql

En-til-mange udvalg i Jooq

Ved brug af JOIN virker ikke til dette.

Din forespørgsel vil være ret ineffektiv, fordi hvis du bruger joinforbindelser på denne måde, opretter du et kartesisk produkt mellem bøgerne og artiklertabellen, hvilket resulterer i en del hukommelse og CPU-forbrug både i databasen og i din Java-klient, før du de-duplikerer alle de meningsløse kombinationer.

Den "korrekte" SQL-tilgang ville være at bruge MULTISET som beskrevet i denne artikel her . jOOQ 3.9 understøtter desværre ikke MULTISET endnu (og heller ikke mange databaser). Så du bør oprette to separate forespørgsler:

  1. Henter alle bøgerne
  2. Henter alle artiklerne

Og brug så noget som Java 8 Streams til at kortlægge dem til et enkelt objekt.

Brug af MULTISET startende fra jOOQ 3.15

Heldigvis er der fra jOOQ 3.15 en klar løsning til at indlejre samlinger i SQL ved hjælp af MULTISET . Din forespørgsel ville se sådan ud:

Brug af refleksion

List<Author> authors =
ctx.select(
      AUTHOR.ID,
      AUTHOR.NAME,
      multiset(
        select(BOOKS.TITLE)
        .from(BOOKS)
        .where(BOOKS.AUTHOR_ID.eq(AUTHOR.ID))
      ).as("books"),
      multiset(
        select(ARTICLES.TITLE)
        .from(ARTICLES)
        .where(ARTICLES.AUTHOR_ID.eq(AUTHOR.ID))
      ).as("articles")
    )
   .from(AUTHOR)
   .where(AUTHOR.ID.eq(id))
   .fetchInto(Author.class);

Brug af typen sikker, annonce -hoc-konvertering

List<Author> authors =
ctx.select(
      AUTHOR.ID,
      AUTHOR.NAME,
      multiset(
        select(BOOKS.TITLE)
        .from(BOOKS)
        .where(BOOKS.AUTHOR_ID.eq(AUTHOR.ID))
      ).as("books").convertFrom(r -> r.map(Record1::value1)),
      multiset(
        select(ARTICLES.TITLE)
        .from(ARTICLES)
        .where(ARTICLES.AUTHOR_ID.eq(AUTHOR.ID))
      ).as("articles").convertFrom(r -> r.map(Record1::value1))
    )
   .from(AUTHOR)
   .where(AUTHOR.ID.eq(id))
   .fetch(Records.mapping(Author::new));

For mere information om MULTISET , se venligst dette blogindlæg , eller de manuelle sektioner:

Brug af SQL/XML eller SQL/JSON fra jOOQ 3.14

Fra jOOQ 3.14 kan du indlejre samlinger via SQL/XML eller SQL/JSON, hvis dit RDBMS understøtter det. Du kan producere et dokument og derefter bruge noget som Gson, Jackson eller JAXB til at kortlægge det tilbage til dine Java-klasser. For eksempel:

List<Author> authors =
ctx.select(
      AUTHOR.ID,
      AUTHOR.NAME,
      field(
        select(jsonArrayAgg(BOOKS.TITLE))
        .from(BOOKS)
        .where(BOOKS.AUTHOR_ID.eq(AUTHOR.ID))
      ).as("books"),
      field(
        select(jsonArrayAgg(ARTICLES.TITLE))
        .from(ARTICLES)
        .where(ARTICLES.AUTHOR_ID.eq(AUTHOR.ID))
      ).as("articles")
    )
   .from(AUTHOR)
   .where(AUTHOR.ID.eq(id))
   .fetchInto(Author.class);

Bemærk, at JSON_ARRAYAGG() samler tomme sæt til NULL , ikke i en tom [] . Hvis det er et problem, skal du bruge COALESCE()




  1. Oracle Indsæt via Vælg fra flere tabeller, hvor én tabel muligvis ikke har en række

  2. Vis alle identitetskolonner i en SQL Server-database:sys.identity_columns

  3. Databasedesign til et multiplayer/single quiz-spil

  4. Mysql bestille varer inden den seneste af 2 datoer