我的控制器
@GetMapping(value="/getAllDetails") public List<PriceListEntity> getAllDetails() { return MyRepository.getAllDetails(); }
我的资料库
@Repository public interface MyRepository extends CrudRepository<TestNativeQ, String> { @Query( value="SELECT qplt.name price_list_name, qplab.status_code, qplab.start_date, (SELECT charge_definition_code FROM oalfsaas_repl.QP_CHARGE_DEFINITIONS_B WHERE charge_definition_id=qplab.charge_definition_id ) chargedefinitioncode " + "FROM PriceListEntity qplab, PriceListLineEntity qplt " + " WHERE qplab.price_list_id =qplt.price_list_id ", nativeQuery = false) public List<PriceListEntity> getAllDetails(); }
实际结果:
[{"ABC", "DEF", "15/05/2018", "XXZ"}]
预期结果
[{name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"}]
该查询已联接多个表,并在列级别进行了子查询。
您实际上正在使用选择进行投影,该选择不返回任何特定对象,而是返回 一个元组 , 该元组 是您在查询中选择的对象数组。无论采用哪种方式制作JSON,都没有名称,只有值。
您需要创建一个DTO来保存要通过JSON中的名称传递的值。
一个最小的示例,具有一个简单的实体,例如:
@Entity @Getter @RequiredArgsConstructor public class TestClass { @Id @GeneratedValue private Long id; @NonNull private String a,b,c; }
并愿意通过-例如-仅a&b可能会有DTO,例如:
a
b
@RequiredArgsConstructor public class TupleDto { @NonNull private String a,b; }
在你的情况下 PriceListDetailsDto
PriceListDetailsDto
仓库可以这样声明:
public interface TestClassRepository extends CrudRepository<TestClass, Long> { @Query(value="SELECT new org.example.TupleDto(tc.a, tc.b) FROM TestClass tc") List<TupleDto> fetchAB(); }
注意 :在上面,使用了操作符new和实体构造函数的完整路径。
new
这样,Spring存储库就知道如何分配选定的字段,并且当从此DTO生成JSON时,将导致具有带有名称(DTO中的名称)的字段。
newJPQL中的运算符只是new在a,b,cjava中调用,因此任何行数据都可以用于构造Java对象,而该对象的类构造函数接受相同的参数数量和类型(并以相同的顺序)so liie new MyEntityObject(a,b,c)。
a,b,c
new MyEntityObject(a,b,c)
注意 :在这种简单情况下,如果原始实体被修改为在c中允许空值并添加相应的构造函数,则可以将其用作DTO。如果您的元组是由许多表构成的,则需要创建一个DTO来保存这些值。