Mysql
 sql >> база данни >  >> RDS >> Mysql

Избиране едно към много в Jooq

Използване на JOIN не работи за това.

Вашата заявка ще бъде доста неефективна, защото ако използвате присъединяване по този начин, вие създавате декартов продукт между книгите и таблицата със статии, което води до доста потребление на памет и процесор както в базата данни, така и във вашия Java клиент, преди да премахнете дублирането на всички безсмислени комбинации.

"Правилният" SQL подход би бил да се използва MULTISET както е описано в тази статия тук . За съжаление, jOOQ 3.9 не поддържа MULTISET все още (нито много бази данни). Така че трябва да създадете две отделни заявки:

  1. Извличане на всички книги
  2. Извличане на всички статии

И след това използвайте нещо като Java 8 Streams, за да ги съпоставите в един обект.

Използване на MULTISET започвайки от jOOQ 3.15

За щастие, започвайки от jOOQ 3.15, има готово решение за вмъкване на колекции в SQL с помощта на MULTISET . Вашата заявка ще изглежда така:

Използване на отражение

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);

Използване на безопасно тип, реклама -hoc преобразуване

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));

За повече информация относно MULTISET , моля, вижте тази публикация в блог , или ръчните секции:

Използване на SQL/XML или SQL/JSON, започвайки от jOOQ 3.14

Започвайки от jOOQ 3.14, можете да вложите колекции чрез SQL/XML или SQL/JSON, ако вашата RDBMS поддържа това. Можете да създадете документ и след това да използвате нещо като Gson, Jackson или JAXB, за да го съпоставите обратно с вашите Java класове. Например:

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);

Имайте предвид, че JSON_ARRAYAGG() агрегира празни набори в NULL , а не в празен [] . Ако това е проблем, използвайте COALESCE()




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Поръчайте SQL от най-силния LIKE?

  2. PHP клас за връзка с база данни

  3. избор на сортиране на таблици за универсални знаци

  4. MySQL:Собствеността на директорията mysql се променя на 'mysql' от 'service_account' при рестартиране на linux сървър

  5. как можем да променим стойността с помощта на радио бутони