Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wybierz jeden do wielu w Jooq

Korzystanie z JOIN nie działa na to.

Twoje zapytanie będzie raczej nieefektywne, ponieważ jeśli używasz złączeń w ten sposób, tworzysz produkt kartezjański między książkami a tabelą artykułów, co skutkuje sporym zużyciem pamięci i procesora zarówno w bazie danych, jak i w kliencie Java, zanim usuniesz wszystkie bezsensowne kombinacje.

„Właściwym” podejściem SQL byłoby użycie MULTISET jak opisano w tym artykule tutaj . Niestety, jOOQ 3.9 nie obsługuje MULTISET jeszcze (ani wiele baz danych). Powinieneś więc utworzyć dwa oddzielne zapytania:

  1. Pobieranie wszystkich książek
  2. Pobieranie wszystkich artykułów

A następnie użyj czegoś takiego jak Java 8 Streams, aby zmapować je w pojedynczy obiekt.

Korzystanie z MULTISET począwszy od jOOQ 3.15

Na szczęście, począwszy od jOOQ 3.15, istnieje gotowe rozwiązanie do zagnieżdżania kolekcji w SQL przy użyciu MULTISET . Twoje zapytanie wyglądałoby tak:

Korzystanie z odbicia

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

Korzystając z sejfu typu, reklama konwersja -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));

Więcej informacji o MULTISET , zapoznaj się z tym wpisem na blogu lub sekcje podręcznika:

Korzystanie z SQL/XML lub SQL/JSON od jOOQ 3.14

Począwszy od jOOQ 3.14, możesz zagnieżdżać kolekcje za pomocą SQL/XML lub SQL/JSON, jeśli Twój RDBMS to obsługuje. Możesz stworzyć dokument, a następnie użyć czegoś takiego jak Gson, Jackson lub JAXB, aby zmapować go z powrotem do swoich klas Java. Na przykład:

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

Zauważ, że JSON_ARRAYAGG() agreguje puste zestawy w NULL , a nie w pusty [] . Jeśli to jest problem, użyj 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. SUMA kwot ze znakiem dolara

  2. Funkcja MySQL ACOS() — zwraca cosinus łuku liczby

  3. Jak korzystać z trwałego połączenia mysqli na różnych stronach

  4. Czy istnieje sposób na zapytanie, czy pole tablicy zawiera określoną wartość w Doctrine2?

  5. MySQL - wyklucz wszystkich zablokowanych użytkowników z wyników