首页 > 解决方案 > Query result in JSON format (key value pair) on using @Query annotation in Spring Boot, Hibernate

问题描述

My Controller

@GetMapping(value="/getAllDetails")
public List<PriceListEntity> getAllDetails() {
    return MyRepository.getAllDetails();
}

My Repository

@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();
}

Actual Result:

[{"ABC", "DEF", "15/05/2018", "XXZ"}]

Expected Result

[{name: "ABC", statuscode: "DEF", startDate: "15/05/2018", chargedefintioncode: "XXZ"}]

The Query has join with more than one table and also subquery at column level.

标签: jsonspring-bootspring-data-jpadtojsonresponse

解决方案


您实际上是在使用您的 select 进行投影,它不返回任何特定对象,而是一个元组,它是您在查询中选择的对象数组。无论以何种方式制作 JSON,都没有名称,只有值。

您需要创建一个 DTO 来保存要在 JSON 中按名称传递的值。

一个最小的例子,有一个简单的实体,如:

@Entity
@Getter
@RequiredArgsConstructor
public class TestClass {
    @Id
    @GeneratedValue
    private Long id;

    @NonNull
    private String a,b,c;
}

并且愿意通过 - 例如 - 只有a&b可能有 DTO,例如:

@RequiredArgsConstructor
public class TupleDto {
    @NonNull
    private String a,b;
}

在你的情况下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和实体构造函数的完整路径。

通过这种方式,Spring 存储库知道如何分配选定的字段,并且在从此 DTO 生成 JSON 时,将导致具有名称的字段(DTO 中的名称)。

JPQL 中的new运算符只是new在 java 中调用-因此,任何行数据a,b,c都可以用于构造 Java 对象,该对象的类构造函数接受相同的参数数量和类型(并且以相同的顺序)所以 liie new MyEntityObject(a,b,c)

还请注意:在这种简单的情况下,如果修改原始实体以允许 c 中的空值并添加相应的构造函数,则可以将原始实体用作 DTO。在您的元组由许多表构成的情况下,您需要创建一个 DTO 来保存这些值。


推荐阅读