Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

permintaan tunggal jooq dengan hubungan satu ke banyak

Ada banyak cara untuk mewujudkan koleksi bersarang dengan SQL, dan / atau dengan jOOQ. Saya hanya membahas beberapa di antaranya:

Menggunakan gabungan

Jika Anda tidak mengumpulkan koleksi tersebut secara mendalam, denormalisasi (meratakan) hasil Anda dengan JOIN mungkin melakukan trik untuk Anda, tanpa menambahkan terlalu banyak overhead karena data sedang diduplikasi. Intinya, Anda akan menulis:

Map<ExperimentRecord, Result<Record>> map =
DSL.using(configuration)
   .select()
   .from(EXPERIMENT)
   .join(TAGS)
   .on(...)
   .fetchGroups(EXPERIMENT);

Peta di atas berisi catatan eksperimen sebagai kunci, dan kumpulan bersarang yang berisi semua tag sebagai nilai.

Membuat dua kueri

Jika Anda ingin mewujudkan grafik objek yang kompleks, menggunakan gabungan mungkin tidak lagi optimal. Sebagai gantinya, Anda mungkin ingin mengumpulkan data di klien Anda dari dua kueri berbeda:

Result<ExperimentRecord> experiments = 
DSL.using(configuration)
   .selectFrom(EXPERIMENT)
   .fetch();

Dan

Result<TagsRecord> tags =
DSL.using(configuration)
   .selectFrom(TAGS)
   .where(... restrict to the previous experiments ...)
   .fetch();
 

Dan sekarang, gabungkan kedua hasil di memori klien Anda, mis.

experiments.stream()
           .map(e -> new ExperimentWithTags(
                e, 
                tags.stream()
                    .filter(t -> e.getId().equals(t.getExperimentId()))
                    .collect(Collectors.toList())
           ));

Mengumpulkan koleksi menggunakan SQL/XML atau SQL/JSON

Pertanyaan ini tidak memerlukannya, tetapi orang lain mungkin menemukan pertanyaan ini dalam mencari cara untuk menghubungkan ke banyak hubungan dengan jOOQ. Saya sudah memberikan jawaban di sini . Dimulai dengan jOOQ 3.14, Anda dapat menggunakan kemampuan SQL/XML atau SQL/JSON RDBMS, lalu menggunakan Jackson, Gson, atau JAXB untuk mengumpulkan koleksi seperti ini:

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

Dimana Experiment adalah kelas Java khusus seperti ini:

class Experiment {
  long id;
  String name;
  List<Tag> tags;
}

class Tag {
  long id;
  String name;
}

Mengumpulkan koleksi menggunakan MULTISET

Bahkan lebih baik dari yang di atas, anda dapat bersembunyi menggunakan SQL/XML atau SQL/JSON di belakang MULTISET baru jOOQ 3.15 dukungan operator . Dengan asumsi kelas Java di atas adalah catatan Java 16 (atau kelas abadi lainnya), Anda bahkan dapat memetakan jenis koleksi bersarang dengan aman ke dalam DTO Anda:

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

Dimana Experiment adalah kelas Java khusus seperti ini:

record Experiment(long id, String name, List<Tag> tags) {}
record Tag(long id, String name) {}

Lihat juga posting blog ini untuk informasi lebih lanjut .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Memfilter baris berbeda dalam SQL

  2. Tambahkan 1 ke bidang

  3. Bagaimana saya bisa mengaktifkan log kueri lambat MySQL tanpa memulai ulang MySQL?

  4. HIBAH minimum yang dibutuhkan oleh mysqldump untuk membuang skema lengkap? (PICU tidak ada!!)

  5. Kesalahan sintaks SQL dengan substring dan charindex