简体   繁体   English

Spring CrudRepository 按结果返回组为 Map

[英]Spring CrudRepository return group by result as a Map

I use CrudRepository to execute a native query, where i use a sum and a group by.我使用 CrudRepository 执行本机查询,其中我使用 sum 和 group by。 I want the query to return the result as a (Hash)Map.我希望查询将结果作为(哈希)映射返回。 My query looks like this:我的查询如下所示:

 @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);

This returns a List of Objects that i manually turn to a Map<String, BigDecimal> using the following code:这将返回一个对象列表,我使用以下代码手动将其转换为Map<String, BigDecimal>

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));```

Which is quite brittle and requires casting.它很脆,需要铸造。 Is there a way to let this query return Map<String, BigDecimal> out of the box?有没有办法让这个查询返回Map<String, BigDecimal>开箱即用?

You can create a custom class to match the result of this query then map list of results to Map.您可以创建自定义 class 以匹配此查询的结果,然后将 map 结果列表与 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());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM