【问题标题】:Spring CrudRepository return group by result as a MapSpring CrudRepository 按结果返回组作为 Map
【发布时间】:2020-02-12 07:24:40
【问题描述】:

我使用 CrudRepository 执行本机查询,其中我使用 sum 和 group by。我希望查询将结果作为(哈希)映射返回。我的查询如下所示:

 @Query(value = "SELECT l.currency, sum(l.price) as total_revenue from line l " + "where ol.id0 = :id0 and l.date_time between :dateStart and :dateEnd and " +
        "(cast(:id1 as text) is null or cast(l.id1 as text) = cast(:id1 as text)) and " +
        "(cast(:id2 as text) is null or cast(l.id2 as text) = cast(:id2 as text))" +
        "group by l.currency" ,
        nativeQuery = true)
List<Object[]> findTotalRevenueByCurrency(@Param("id0") UUID id0,
                                                     @Param("dateStart") Instant dateTimeStart,
                                                     @Param("dateEnd") Instant dateTimeEnd,
                                                     @Param("id1") UUID id1,
                                                     @Param("id2") UUID id2);

这将返回一个对象列表,我使用以下代码手动将其转换为 Map&lt;String, BigDecimal&gt;

var result = orderLineRepository.findAveragePriceByCurrency(id0, orderDate.minus(2, DAYS), orderDate.plus(2, DAYS), id1, id2);

Map<String, BigDecimal> revenueByCurrency = result.stream()
    .map(arr -> Map.of((String) arr[0], (BigDecimal) arr[1]))
    .flatMap(m -> m.entrySet().stream())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));```

它很脆,需要铸造。有没有办法让这个查询返回Map&lt;String, BigDecimal&gt; 开箱即用?

【问题讨论】:

  • 你试过返回类型为Map&lt;String,String&gt;吗?

标签: java sql spring jpa spring-data-jpa


【解决方案1】:

您可以创建一个自定义类来匹配此查询的结果,然后将结果列表映射到 Map。

public class CustomQueryResult {
 //class properties
 public CustomQueryResult(String currency, BigDecimal price) {
    //assign 
 }
}
@Query(value = "SELECT new CustomQueryResult(l.currency, sum(l.price) as total_revenue) from line l " + "where ol.id0 = :id0 and l.date_time between :dateStart and :dateEnd and " +
        "(cast(:id1 as text) is null or cast(l.id1 as text) = cast(:id1 as text)) and " +
        "(cast(:id2 as text) is null or cast(l.id2 as text) = cast(:id2 as text))" +
        "group by l.currency" ,
        nativeQuery = true)
List<CustomQueryResult> findTotalRevenueByCurrency(@Param("id0") UUID id0,
                                                     @Param("dateStart") Instant dateTimeStart,
                                                     @Param("dateEnd") Instant dateTimeEnd,
                                                     @Param("id1") UUID id1,
                                                     @Param("id2") UUID id2);

var result = orderLineRepository.findAveragePriceByCurrency(id0, orderDate.minus(2, DAYS), orderDate.plus(2, DAYS), id1, id2);

 Map<String, BigDecimal> revenueByCurrency = result.stream()
                .collect(Collectors.toMap(k -> k.getCurrency(), v -> v.getPrice());

【讨论】:

    猜你喜欢
    • 2018-06-02
    • 2019-03-07
    • 2015-04-25
    • 2015-09-10
    • 2015-11-26
    • 2015-08-26
    • 1970-01-01
    • 2017-03-09
    • 2018-11-13
    相关资源
    最近更新 更多