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