为什么JPA原生查询返回对象仅能拿到值没有对应字段键
问题原因
你当前接口返回仅含值无字段键的核心原因是:你在Repository层的原生查询定义的返回类型为List<Object[]>,JPA处理该类返回值时只会按SQL中select字段的顺序存储对应值,不会自动绑定字段名做映射,Spring MVC序列化该数组结构时自然只会输出纯值序列,没有字段键。
解决方法
方法1:用Map类型接收结果(快速实现无需新建类)
直接将Repository、Dao、Controller三层的返回值类型从List<Object[]>全量替换为List<Map<String, Object>>即可。
修改示例:
// Repository层修改 @Query(value = "select distinct u.first_name, u.last_name, u.full_name, u.id from public.user u inner join public.users_group ug on u.id = ug.user_id and ug.group_list_id=1 WHERE status=1 ORDER BY u.id DESC", nativeQuery = true) List<Map<String, Object>> getAllInstructors();
JPA会自动把查询字段名作为Map的key,对应值作为Map的value,序列化后就是你需要的键值对结构。
方法2:自定义DTO/投影接口接收(生产环境更推荐,类型安全)
方式A:接口投影(实现最简单)
定义和查询字段匹配的投影接口:
public interface InstructorProjection { // getter方法名和数据库字段驼峰对应,first_name对应getFirstName() String getFirstName(); String getLastName(); String getFullName(); Long getId(); }
将各层返回类型改为List<InstructorProjection>即可,Spring Data JPA会自动完成字段映射。
方式B:实体DTO类
定义带全参构造的DTO类:
public class InstructorDTO { private String firstName; private String lastName; private String fullName; private Long id; // 构造参数顺序要和SQL select字段顺序完全一致 public InstructorDTO(String firstName, String lastName, String fullName, Long id) { this.firstName = firstName; this.lastName = lastName; this.fullName = fullName; this.id = id; } // 补全所有字段的getter、setter方法 }
如果是JPQL查询可以直接在select语句中new该DTO,原生SQL则搭配@SqlResultSetMapping注解完成映射即可。
内容的提问来源于stack exchange,提问作者adelz
相关产品推荐
相关产品推荐

