使用JPA / QueryDSL的类似Pivot的结果

时间:2015-04-25 08:22:26

标签: java sql jpa pivot 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 for Actitivy to ActivityName - 活动可能有不同的名称(例如跑步,慢跑)

一个人可能对某个特定活动具有一定的水平,并且可以执行多个活动(每个活动都有一个定义的级别)。

  • 应该搜索活动名称(例如,跑步等)作为参数(活动名称列表)
  • 因此,应该找到执行相关活动的所有人。
  • 结果应包含所有搜索相关级别,人员姓名和人员活动总和的活动

以下数据示例:

  • Person =(id = 1,name = Bob)
  • Person =(id = 2,name = Mary)
  • 活动=(1,...)
  • 活动=(2,...)
  • ActivityName =(activity_id = 1,name =&#34; jogging&#34;)
  • ActivityName =(activity_id = 1,name =&#34;正在运行&#34;)
  • ActivityName =(activity_id = 2,name =&#34; dance&#34;)
  • ActivityLevel =(person_id = 1,activity_id = 1,level = 0.7f)
  • ActivityLevel =(person_id = 1,activity_id = 2,level = 0.1f)
  • ActivityLevel =(person_id = 2,activity_id = 1,level = 0.5f)

搜索“&#34;跑步&#34;或者&#34;跳舞&#34;应该得到这样的结果:

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 个答案:

答案 0 :(得分:2)

Pure JPA&amp; QueryDsl仅适用于实体。 因此,您可以创建一个聚合您正在查找的数据的数据库视图,并将其映射到一个新实体,您只需查询该实体。

另一个解决方案是使用QueryDsl的本机jpa查询支持。 见http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html下半部分。您需要最低的段落(查询和项目到DTO)。

归结为:

  • 通过指向db(架构)生成Q类(我不确定为什么需要它,但它在文档中)
  • 使用com.mysema.query.jpa.sql.JPASQLQuery类构建查询
  • 确保在列表方法
  • 中列出查询中的所有必要结果字段
  • 创建一个可以投影结果的dto bean类
  • 将结果投影到dto类