【问题标题】:Spring Data Query Map<String, Integer> non unique resultSpring Data Query Map<String, Integer> 非唯一结果
【发布时间】:2023-03-14 17:45:02
【问题描述】:

我对数据库表有这个查询:

SELECT sales_deadline_by_retail AS 'type', COUNT(*) AS 'amount'
FROM (SELECT CASE
                 WHEN deadline_by_retail <= 3 THEN 'Less 3'
                 WHEN deadline_by_retail <= 7 THEN '4 - 7'
                 WHEN deadline_by_retail <= 15 THEN '8 - 15'
                 WHEN deadline_by_retail <= 30 THEN '16 - 30'
                 WHEN deadline_by_retail <= 60 THEN '31 - 60'
                 WHEN deadline_by_retail <= 120 THEN '61 - 120'
                 WHEN deadline_by_retail > 120 THEN 'More 120'
                 ELSE 'Undefined' END sales_deadline_by_retail
      FROM sales_of_tech
      WHERE seller_id = 'B71E005056AD35EB11E6CD0C7B7CC210'
        and warehouse_id = '9F7E005056AD35EB11E6FD987DF6600C'
        and date between '2020-01-01' and '2020-01-31 23:59:59') d
GROUP BY sales_deadline_by_retail

Spring 数据查询如下:

    @Query(value = "SELECT sales_deadline_by_retail AS 'type', COUNT(*) AS 'amount' FROM " +
            "(SELECT CASE WHEN deadline_by_retail <= 3 THEN 'Less 3' " +
            "WHEN deadline_by_retail <= 7 THEN '4 - 7' " +
            "WHEN deadline_by_retail <= 15 THEN '8 - 15' " +
            "WHEN deadline_by_retail <= 30 THEN '16 - 30' " +
            "WHEN deadline_by_retail <= 60 THEN '31 - 60' " +
            "WHEN deadline_by_retail <= 120 THEN '61 - 120' " +
            "WHEN deadline_by_retail > 120 THEN 'More 120'' " +
            "ELSE 'Undefined' END sales_deadline_by_retail " +
            "FROM sales_of_tech WHERE seller_id = ?1 and warehouse_id = ?2 and date between ?3 and ?4) d " +
            "GROUP BY sales_deadline_by_retail", nativeQuery = true)
    Map<String, Integer> getGraphByDeadlineByRetail(String sellerId, String jobId, Date start, Date end);

查询调用异常:

javax.persistence.NonUniqueResultException: query did not return a unique result: 8

我知道查询没有返回唯一结果,我尝试将数据放入 Map。我知道地图“不是真正的收藏”,但我该如何解决这个问题?顺便说一句,我也尝试在模型中嵌入数据并在查询本身中创建一个对象,但在这种情况下,数据的输入和转换到模型时出现了问题。

更新 1: 我试图将数据保存到这样的模型中:

public class PairTypeAmount {
    private String type;
    private int amount;
    // setter and getters
}

新的查询变量和方法名:

List<PairTypeAmount> getGraphByDeadlineByRetail(String sellerId, String jobId, Date start, Date end);

错误:

No converter found capable of converting from type 
[org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] 
to type [com.iwis.dwhconnector.models.PairTypeAmount]

【问题讨论】:

  • 我使用带有 list 响应的 SQL 查询,然后用 iter 解析它

标签: java sql sql-server spring


【解决方案1】:

您可以创建一个包含类型和金额的 POJO,然后从查询中返回。类似:-

public class SalesTypeAmount{
  String type;
  int amount;
  //getter, setter etc.
}

Change repo method:-
List<SalesTypeAmount> getGraphByDeadlineByRetail(String sellerId, String jobId, Date start, Date end);

【讨论】:

  • 谢谢你的想法。不幸的是,我遇到了另一个问题。请检查更新。
  • 您需要将 POJO 与查询结果进行映射。比如使用 SQLResultSetMapping:- ``` @SqlResultSetMapping(name = “test”, classes = { @ConstructorResult( targetClass = SalesTypeAmount.class, columns = { @ColumnResult(name = “type”)... } ) } ) @ Query( query = , resultSetMapping = "test" ) ``` 参考baeldung.com/…中的第3、4节。
【解决方案2】:

我看不到在 JpaRepository 中使用本机查询的方法。您可以像这样使用实体管理器来实现您的存储库方法:

Map<String, Integer> postCountByYearMap = entityManager.createQuery("SELECT sales_deadline_by_retail AS 'type', COUNT(*) AS 'amount' FROM " +
         "(SELECT CASE WHEN deadline_by_retail <= 3 THEN 'Less 3' " +
         "WHEN deadline_by_retail <= 7 THEN '4 - 7' " +
         "WHEN deadline_by_retail <= 15 THEN '8 - 15' " +
         "WHEN deadline_by_retail <= 30 THEN '16 - 30' " +
         "WHEN deadline_by_retail <= 60 THEN '31 - 60' " +
         "WHEN deadline_by_retail <= 120 THEN '61 - 120' " +
         "WHEN deadline_by_retail > 120 THEN 'More 120'' " +
         "ELSE 'Undefined' END sales_deadline_by_retail " +
         "FROM sales_of_tech WHERE seller_id = ?1 and warehouse_id = ?2 and date between ?3 and ?4) d " +
         "GROUP BY sales_deadline_by_retail", Tuple.class)
         .getResultStream()
         .collect(
              Collectors.toMap(
                   tuple -> ((String) tuple.get("type")),
                   tuple -> ((Number) tuple.get("amount")).intValue()
              )
         );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-06
    • 2012-04-27
    • 2019-11-05
    • 2015-07-08
    • 2012-05-17
    • 2012-05-26
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多