如何遍历JPA查询返回的List<Object>结果并正确获取字段值
问题根因
你写的JPQL查询指定返回两个字段(divisionName、count(stundeName)),Spring Data JPA对这种多字段返回的查询,默认返回的List<Object>中每个元素都是Object数组,数组元素顺序和你select的字段顺序完全对应,不存在名为count的类属性,所以你用反射查找count字段会直接抛出NoSuchFieldException。另外你代码里getDeclaredField的参数用了单引号,Java中单引号代表char类型,字符串参数需要用双引号,这也是语法错误点,就算改了引号也拿不到值,因为本身就没有对应字段。
解决方案
方案1:直接强转为Object数组取值(快速实现)
不需要修改原有Repository定义,直接遍历强转即可:
for (Object obj : countList) { // 每个元素本质是Object数组,顺序和select字段顺序一致 Object[] result = (Object[]) obj; String divisionName = (String) result[0]; Long count = (Long) result[1]; // 在这里写你自己的分类归类逻辑即可 System.out.println("分类:" + divisionName + ",数量:" + count); }
方案2:自定义DTO接收返回结果(更规范,易维护)
避免硬编码数组索引容易写错的问题,业务场景复杂时更推荐:
- 先定义接收数据的DTO类,要提供和查询返回字段顺序、类型完全匹配的构造方法:
public class DivisionCountDTO { private String divisionName; private Long count; public DivisionCountDTO(String divisionName, Long count) { this.divisionName = divisionName; this.count = count; } // 按需添加getter、setter方法 public String getDivisionName() { return divisionName; } public Long getCount() { return count; } }
- 修改Repository层的@Query注解,用JPQL构造函数表达式指定返回DTO:
// 注意new后面要写DTO的完整全类名,比如你的DTO放在com.example.dto包下就写com.example.dto.DivisionCountDTO @Query("select new com.example.dto.DivisionCountDTO(divisionName, count(stundeName)) FROM StudentDetails GROUP BY divisionName") public List<DivisionCountDTO> getDivisionCount();
- Service层直接遍历DTO获取值即可:
List<DivisionCountDTO> countList = studentDetailsRepository.getDivisionCount(); for (DivisionCountDTO dto : countList) { String divisionName = dto.getDivisionName(); Long count = dto.getCount(); // 在这里写分类归类逻辑 }
内容的提问来源于stack exchange,提问作者Rahul_Mandhane
相关产品推荐
相关产品推荐

