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

jooq единична заявка с връзка едно към много

Има много начини за материализиране на вложена колекция с SQL и/или с jOOQ. Просто минавам през някои от тях:

Използване на съединения

Ако не вложите дълбоко тези колекции, денормализиране (изравняване) на вашите резултати с JOIN може да свърши работа вместо вас, без да добавяте твърде много разходи, тъй като данните се дублират. По същество ще напишете:

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

Горната карта съдържа експериментални записи като ключове и вложени колекции, съдържащи всички тагове като стойности.

Създаване на две заявки

Ако искате да материализирате сложна обектна графика, използването на съединения може вече да не е оптимално. Вместо това вероятно искате да съберете данните във вашия клиент от две отделни заявки:

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

И

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

И сега обединете двата резултата в паметта на вашия клиент, напр.

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

Вложени колекции с помощта на SQL/XML или SQL/JSON

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

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

Където Experiment е персонализиран Java клас като този:

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

class Tag {
  long id;
  String name;
}

Влагане на колекции с помощта на MULTISET

Дори по-добре от горното, можете да се скриете с помощта на SQL/XML или SQL/JSON зад новия MULTISET на jOOQ 3.15 операторска поддръжка . Ако приемем, че горните класове на Java са записи на Java 16 (или други неизменни класове), можете дори да картографирате безопасно вложени колекции във вашите DTO:

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

Където Experiment е персонализиран Java клас като този:

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

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Оптимизирайте извикването на данни в JDBC в JTable

  2. Вмъкване в MySQL от PHP (jQuery/AJAX)

  3. функция за изграждане на часови зони в уеб приложение на PHP

  4. ограничението за проверка няма да работи mysql

  5. Има ли добър начин за извършване на SQL изхвърляне на MySQL база данни в DataGrip?