Pivot-подобный результат с JPA/QueryDSL

мы используем JPA2, Spring Data и QueryDSL в нашем проекте. У меня есть следующие таблицы и связанные объекты JPA:

table Person (id, ...) 

table Activity (id, type, ...)

@Entity
@Configurable
public class Activity {
   @ElementCollection
   @CollectionTable(joinColumns = @JoinColumn(name = "ACTIVITY_ID"))
   @NotEmpty
   @Valid
   private Set<ActivityName> names = new HashSet<>();

table ActivityName(activity_id, name, ...) 

@Embeddable
  @Immutable
  @Table(uniqueConstraints = @UniqueConstraint(columnNames = "NAME"))
  public static class ActivityName { ... }

table ActivityLevel(person_id, activity_id, level) 

@Entity
@Immutable
@Validated
public final class ActivityLevel{...}

1..n для Actitivy to ActivityName-действие может иметь разные имена (например, бег, бег трусцой)

человек может иметь определенный уровень для данной деятельности и может выполнять несколько действий (каждый с определенным уровнем).

  • должен быть поиск с именами действий (например, запуск и т. д.) в качестве параметров (а список имен действий)
  • в результате должны быть найдены все лица, которые выполняют соответствующую деятельность.
  • результат должен содержать все действия по поиску с соответствующим уровнем, именем человека и общей суммой действий лиц

пример следующие данные:

  • Person = (id=1, name=Bob)
  • Person = (id=2, name=Mary)
  • Activity = (1,...)
  • действие = (2, ...)
  • ActivityName = (activity_id=1, name ="бег трусцой")
  • ActivityName = (activity_id=1, name = "running")
  • ActivityName = (activity_id=2, name = "танцы")
  • ActivityLevel = (person_id=1, activity_id=1, level=0.7 f)
  • ActivityLevel = (person_id=1, activity_id=2, level=0.1 f)
  • ActivityLevel = (person_id=2, activity_id=1, level=0.5 f)

поиск людей, которые "бег" или "танцы" должны получить такой результат:

Person[Name]   ActitiyName  ActivityLevel ActitiyName  ActivityLevel  Sum
Bob             running         0.7         dancing         0.1       0.8
Mary            running         0.5                                   0.5          

Мой Вопрос: есть ли способ JPA QL / QueryDSL получить такой результат с один выражение / проекции? У меня уже есть многоэтапное решение-выбор имен действий и уровней, выполнение группировки и суммы с помощью Java8. Если я делаю группировку с querydsl, я не получаю записи одного уровня. И наоборот, в моем решении я должен выполнить несколько других шагов.

было бы неплохо узнать, возможно ли это просто с помощью запроса.

1 ответов


Pure JPA & QueryDsl работает только с сущностями. Таким образом, вы можете создать представление БД, которое агрегирует данные, которые вы ищете, и сопоставляет их с новой сущностью, которую вы можете просто запросить.

другим решением является использование собственной поддержки запросов JPA QueryDsl. См.http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html нижняя половина. Вам понадобится самый низкий абзац (запрос и проект в DTO).

все сводится кому:

  • генерировать Q классы, указывая на db (schema) (я не уверен, почему это необходимо, но это в документах)
  • построить запрос с помощью com.mysema.запрос.jpa.язык SQL.Класс JPASQLQuery
  • обязательно перечислите все необходимое поле результата из запроса в методе list
  • создайте класс DTO bean, в который вы можете проецировать результат
  • проецируйте результат в класс dto