2017-10-04 271 views
0

我期待创建一个REST控制器,它将返回各种对象的排序列表。使用JPA对集合进行分组和排序

我创建了一个DTO持有这些集合类似以下,但是这是行不通的,因为它会组由实体:

public class AllReportsDTO { 

private List<AReport> aReports; 
private List<BReport> bReports; 
private List<CReport> cReports; 
... 
} 

然后我有以下的域对象

@Entity 
@Table(name = "a_report") 
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) 
public class AReport implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
private Long id; 

@Column(name = "title") 
private String title; 

@Column(name = "description") 
private String description; 

@Column(name = "time_of_report") 
private ZonedDateTime timeOfReport; 

每个报告一个。

我想要做的是创建一个端点,它将返回所有这些报告的列表,但按照报告的时间顺序,而不是按报告进行分组。我怎样才能做到这一点?

我试过用HQL查询将它写入存储库并按时间分组,但问题是每个时间字段在每个报告中都有一个不同的名称,因为这个系统正在其他地方使用,所以我无法更改每个报告中的名称。

+1

做独立的类,为您的“报告”实体的JSON表示与使用@JsonPropertyOrder –

+0

嗨Sujal , 非常感谢您的回复。问题在于每个报告只有很少的变量是共同的,所以很难将JSON表示形式作为一个常见的视图。最大的问题是,当时的变量名称的命名是不同的,我不能改变,所以很难订购。 – Megadec

+1

我不明白。首先:一个'Set'会让你的订单时间过时,因为它保证没有订单。你必须切换到'List'。第二:如果存在不同的实体,则通过单独选择它们并在每个查询中按当前时间字段排序。 –

回答

1

我不会尝试纯粹的HQL解决方案或ORM的解决方案。我会去Java方式。

  1. 添加接口

    public interface ITimedReport { 
        ZonedDateTime getTime(); 
    } 
    
  2. 使所有的报表类通过返回自己的时间戳实现了这个接口
  3. 添加的方法getAllReportsAllReportsDTO。 此方法应填写所有报告的List<ITimedReport>,然后使用Comparator<ITimedReport>对列表进行排序。该比较器将依靠getTime()进行比较。

您可以在界面中添加任何meaningfull的报告,像一个的getTitle,getDescription,...

+0

谢谢你Genu!这是一个非常优雅的解决方案。 – Megadec

2

您可以创建对您的集合进行排序的方法。尝试去熟练使用这一个

Collections.sort(aReports, new Comparator<Object>() { 
    public int compare(MyObject o1, Object o2) { 
     return o1.getTimeOfReport().compareTo(o2.getTimeOfReport()); 
    } 
}); 
相关问题