Pra*_*lan 85 java spring jpa spring-mvc repository
我正在使用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();
Run Code Online (Sandbox Code Playgroud)
它的工作和结果如下:
[
[1, "a1"],
[2, "a2"]
]
Run Code Online (Sandbox Code Playgroud)
我想得到这样的东西:
[
{ "cnt":1, "answer":"a1" },
{ "cnt":2, "answer":"a2" }
]
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
man*_*ish 200
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;
}
}
Run Code Online (Sandbox Code Playgroud)
第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();
}
Run Code Online (Sandbox Code Playgroud)
MyBean并且它在包中com.path.to,那么bean的完全限定路径将是com.path.to.MyBean.简单地提供MyBean将不起作用(除非bean类在默认包中).new关键字调用bean类构造函数.SELECT new com.path.to.MyBean(...)会工作,而SELECT com.path.to.MyBean(...)不会.@Query("SELECT ..."),或@Query(value = "SELECT ..."),或@Query(value = "SELECT ...", nativeQuery = false)将工作,而@Query(value = "SELECT ...", nativeQuery = true)不会工作.这是因为本机查询在没有修改的情况下传递给JPA提供程序,因此会针对底层RDBMS执行.由于new并且com.path.to.MyBean不是有效的SQL关键字,因此RDBMS会抛出异常.如上所述,new ...语法是JPA支持的机制,适用于所有JPA提供程序.但是,如果查询本身是不是一个JPA查询,也就是说,它是一种天然的查询时,new ...作为查询被传递直接到底层RDBMS,不明白的语法是行不通的new,因为它不是一部分的关键字SQL标准.
在这种情况下,需要使用Spring Data Projection接口替换bean类.
第1步:声明投影界面
package com.path.to;
public interface SurveyAnswerStatistics {
String getAnswer();
int getCnt();
}
Run Code Online (Sandbox Code Playgroud)
第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();
}
Run Code Online (Sandbox Code Playgroud)
使用SQL AS关键字将结果字段映射到投影属性以进行明确映射.
ozg*_*gur 17
这个SQL查询返回List <Object []>会.
你可以这样做:
@RestController
@RequestMapping("/survey")
public class SurveyController {
@Autowired
private SurveyRepository surveyRepository;
@RequestMapping(value = "/find", method = RequestMethod.GET)
public Map<Long,String> findSurvey(){
List<Object[]> result = surveyRepository.findSurveyCount();
Map<Long,String> map = null;
if(result != null && !result.isEmpty()){
map = new HashMap<Long,String>();
for (Object[] object : result) {
map.put(((Long)object[0]),object[1]);
}
}
return map;
}
}
Run Code Online (Sandbox Code Playgroud)
ren*_*ena 12
我知道这是一个古老的问题,它已经得到了解答,但这是另一种方法:
@Query("select new map(count(v) as cnt, v.answer) from Survey v group by v.answer")
public List<?> findSurveyCount();
Run Code Online (Sandbox Code Playgroud)
使用接口,您可以获得更简单的代码。无需创建和手动调用构造函数
第1步:使用必填字段声明界面:
public interface SurveyAnswerStatistics {
String getAnswer();
Long getCnt();
}
Run Code Online (Sandbox Code Playgroud)
步骤2:在接口中选择与getter名称相同的列,并从存储库方法返回intefrace:
public interface SurveyRepository extends CrudRepository<Survey, Long> {
@Query("select v.answer as answer, count(v) as cnt " +
"from Survey v " +
"group by v.answer")
List<SurveyAnswerStatistics> findSurveyCount();
}
Run Code Online (Sandbox Code Playgroud)
定义一个自定义pojo类,例如sureveyQueryAnalytics并将查询返回的值存储在您的自定义pojo类中
@Query(value = "select new com.xxx.xxx.class.SureveyQueryAnalytics(s.answer, count(sv)) from Survey s group by s.answer")
List<SureveyQueryAnalytics> calculateSurveyCount();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118381 次 |
| 最近记录: |