java - 使用 JPA/QueryDSL 的类似数据透视的结果

标签 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 用于 Activity 到 ActivityName - 一个 Activity 可能有不同的名称(例如运行、慢跑)

一个人可能对给定的 Activity 具有一定的水平,并且可以执行多项 Activity (每个 Activity 都有一个定义的级别)。

  • 应该使用 Activity 名称(例如运行等)作为参数( Activity 名称列表)进行搜索
  • 因此,应该找到执行相关 Activity 的所有人。
  • 结果应包含搜索到的所有 Activity 及其对应的级别、人员姓名以及人员 Activity 的总和

例如以下数据:

  • 人 = (id=1, name=Bob)
  • 人 = (id=2, name=Mary)
  • Activity = (1, ...)
  • Activity = (2, ...)
  • ActivityName = (activity_id=1, name ="慢跑")
  • ActivityName = (activity_id=1, name = "running")
  • ActivityName = (activity_id=2, name = "dancing")
  • 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)

搜索正在“运行”或“跳舞”的人应该得到如下结果:

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 方法可以通过一个 表达式/投影获得这样的结果?我已经拥有的是一个多步骤解决方案——选择 Activity 名称和级别,使用 Java8 执行分组和求和。如果我使用 querydsl 进行分组,我不会得到单级条目。反之亦然,在我的解决方案中,我必须执行其他几个步骤。

很高兴知道这是否可以仅通过使用查询来实现。

最佳答案

纯 JPA 和 QueryDsl 仅适用于实体。 因此,您可以制作一个数据库 View 来聚合您要查找的数据并将其映射到一个新实体,您可以简单地查询该实体。

另一种解决方案是使用 QueryDsl 的原生 jpa 查询支持。 参见 http://www.querydsl.com/static/querydsl/3.6.1/reference/html/ch02.html下半区。您需要最低的段落(查询并转换到 DTO)。

归结为:

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

关于java - 使用 JPA/QueryDSL 的类似数据透视的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29862802/

相关文章:

java - 如何随机播放 ArrayList 的特定范围?

java - groovy xml解析函数

java.util.date() 始终显示 GMT 时间

MySql SP 不工作

mysql - 如何在 Spring MVC 中使用 SQL 实现审计跟踪?

mysql - Hibernate Criteria Query 使用 MySQL REPLACE 和 CONCAT 函数

java - JPA native 查询转换失败异常: Failed to convert from type

java - 是否可以在不创建实例的情况下检查一个类是否在java中扩展另一个类?

sql - PostgreSQL 错误 : query has no destination for result data

MySQL-SUM(GROUP BY)?