当前位置: 首页 > 面试题库 >

如何从Spring Data JPA GROUP BY查询返回自定义对象

商弘义
2023-03-14
问题内容:

我正在使用Spring Data JPA开发Spring Boot应用程序。我正在使用自定义JPQL查询来按某个字段分组并获取计数。以下是我的存储库方法。

@Query(value = "select count(v) as cnt, v.answer from Survey v group by v.answer")
public List<?> findSurveyCount();

它正在工作,结果如下:

[
  [1, "a1"],
  [2, "a2"]
]

我想得到这样的东西:

[
  { "cnt":1, "answer":"a1" },
  { "cnt":2, "answer":"a2" }
]

我该如何实现?


问题答案:
本文向大家介绍如何从Spring Data JPA GROUP BY查询返回自定义对象相关面试题,主要包含被问及如何从Spring Data JPA GROUP BY查询返回自定义对象时的应答技巧和注意事项,需要的朋友参考一下

JPQL查询解决方案
JPA规范中的 JPQL查询支持此功能。

步骤1:声明一个简单的bean类

package com.path.to;

public class SurveyAnswerStatistics {
  private String answer;
  private Long   cnt;

  public SurveyAnswerStatistics(String answer, Long cnt) {
    this.answer = answer;
    this.count  = cnt;
  }
}

步骤2:从存储库方法返回bean实例

public interface SurveyRepository extends CrudRepository<Survey, Long> {
    @Query("SELECT " +
           "    new com.path.to.SurveyAnswerStatistics(v.answer, COUNT(v)) " +
           "FROM " +
           "    Survey v " +
           "GROUP BY " +
           "    v.answer")
    List<SurveyAnswerStatistics> findSurveyCount();
}

重要笔记

  1. 确保提供到bean类的标准路径,包括包名。例如,如果bean类被调用MyBean并且在包中com.path.to,则指向bean的标准路径将为com.path.to.MyBean。仅提供MyBean将不起作用(除非bean类在默认程序包中)。
  2. 确保使用new关键字调用bean类的构造函数。SELECT new com.path.to.MyBean(...)会工作,而SELECT com.path.to.MyBean(...)不会。
  3. 确保以与bean构造函数中期望的顺序完全相同的顺序传递属性。尝试以不同顺序传递属性将导致异常。
  4. 确保查询是有效的JPA查询,也就是说,它不是本机查询。@Query("SELECT ...")或者@Query(value = "SELECT ..."),或@Query(value = "SELECT ...", nativeQuery = false)将工作,而@Query(value = "SELECT ...", nativeQuery = true)将无法正常工作。这是因为本机查询无需修改就传递给JPA提供程序,并照此针对基础RDBMS执行。由于newcom.path.to.MyBean是无效的SQL关键字,因此RDBMS会引发异常。

本机查询解决方案

如上所述,该new ...语法是JPA支持的机制,并且可与所有JPA提供程序一起使用。但是,如果查询本身不是JPA查询,即它是本机查询,则new …语法将不起作用,因为该查询直接传递给基础RDBMS,该RDBMS不理解该new关键字,因为它不是该关键字的一部分。 SQL标准。

在这种情况下,需要用Spring Data Projection接口替换bean类。

步骤1:声明投影界面

package com.path.to;

public interface SurveyAnswerStatistics {
  String getAnswer();

  int getCnt();
}

步骤2:从查询中返回投影的属性

public interface SurveyRepository extends CrudRepository<Survey, Long> {
    @Query(nativeQuery = true, value =
           "SELECT " +
           "    v.answer AS answer, COUNT(v) AS cnt " +
           "FROM " +
           "    Survey v " +
           "GROUP BY " +
           "    v.answer")
    List<SurveyAnswerStatistics> findSurveyCount();
}

使用SQL AS关键字将结果字段映射到投影属性,以进行明确的映射。



 类似资料: