JPA/QueryDSL 的类似枢轴的结果
Pivot-like result with JPA/QueryDSL
我们在项目中使用 JPA2、Spring 数据和 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 用于 Activity 到 ActivityName - activity 可能有不同的名称(例如 运行、jogging)
对于给定的 activity,一个人可能具有一定的水平,并且可以执行多项活动(每个活动都有一个定义的水平)。
- 应该使用 activity 个名称(例如 运行 等)作为参数(activity 个名称的列表)进行搜索
- 因此,应该找到执行相关 activity 的所有人员。
- 结果应包含搜索到的所有活动及其相应级别、人员姓名和人员活动的总和
例如以下数据:
- 人 = (id=1, name=Bob)
- 人 = (id=2, name=Mary)
- Activity = (1, ...)
- Activity = (2, ...)
- Activity姓名=(activity_id=1,姓名="jogging")
- Activity姓名=(activity_id=1,姓名="running")
- Activity姓名=(activity_id=2,姓名="dancing")
- Activity等级=(person_id=1,activity_id=1,等级=0.7f)
- Activity等级=(person_id=1,activity_id=2,等级=0.1f)
- Activity等级=(person_id=2,activity_id=1,等级=0.5f)
搜索 "running" 或 "dancing" 的人应该得到如下结果:
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 方法通过 one 表达式/投影获得这样的结果?我已经拥有的是一个多步骤解决方案 - 选择 activity 名称和级别,执行分组并使用 Java8 求和。如果我使用 querydsl 进行分组,我不会得到单级条目。反之亦然,在我的解决方案中,我必须执行其他几个步骤。
很高兴知道这是否可以仅通过查询实现。
纯 JPA 和 QueryDsl 仅适用于实体。
因此,您可以制作一个数据库视图来聚合您要查找的数据并将其映射到一个新实体,您可以简单地查询它。
另一种解决方案是使用 QueryDsl 的本机 jpa 查询支持。
请参阅 http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html 下半部分。您需要最低的段落(查询并投射到 DTO)。
归结为:
- 通过指向数据库(架构)生成 Q classes(我不确定为什么需要这样做,但它在文档中)
- 使用 com.mysema.query.jpa.sql.JPASQLQuery class
构建查询
- 确保列出列表方法中查询的所有必要结果字段
- 创建一个可以将结果投影到的 dto bean class
- 将结果投影到 dto class
我们在项目中使用 JPA2、Spring 数据和 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 用于 Activity 到 ActivityName - activity 可能有不同的名称(例如 运行、jogging)
对于给定的 activity,一个人可能具有一定的水平,并且可以执行多项活动(每个活动都有一个定义的水平)。
- 应该使用 activity 个名称(例如 运行 等)作为参数(activity 个名称的列表)进行搜索
- 因此,应该找到执行相关 activity 的所有人员。
- 结果应包含搜索到的所有活动及其相应级别、人员姓名和人员活动的总和
例如以下数据:
- 人 = (id=1, name=Bob)
- 人 = (id=2, name=Mary)
- Activity = (1, ...)
- Activity = (2, ...)
- Activity姓名=(activity_id=1,姓名="jogging")
- Activity姓名=(activity_id=1,姓名="running")
- Activity姓名=(activity_id=2,姓名="dancing")
- Activity等级=(person_id=1,activity_id=1,等级=0.7f)
- Activity等级=(person_id=1,activity_id=2,等级=0.1f)
- Activity等级=(person_id=2,activity_id=1,等级=0.5f)
搜索 "running" 或 "dancing" 的人应该得到如下结果:
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 方法通过 one 表达式/投影获得这样的结果?我已经拥有的是一个多步骤解决方案 - 选择 activity 名称和级别,执行分组并使用 Java8 求和。如果我使用 querydsl 进行分组,我不会得到单级条目。反之亦然,在我的解决方案中,我必须执行其他几个步骤。
很高兴知道这是否可以仅通过查询实现。
纯 JPA 和 QueryDsl 仅适用于实体。 因此,您可以制作一个数据库视图来聚合您要查找的数据并将其映射到一个新实体,您可以简单地查询它。
另一种解决方案是使用 QueryDsl 的本机 jpa 查询支持。 请参阅 http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html 下半部分。您需要最低的段落(查询并投射到 DTO)。
归结为:
- 通过指向数据库(架构)生成 Q classes(我不确定为什么需要这样做,但它在文档中)
- 使用 com.mysema.query.jpa.sql.JPASQLQuery class 构建查询
- 确保列出列表方法中查询的所有必要结果字段
- 创建一个可以将结果投影到的 dto bean class
- 将结果投影到 dto class