在spring boot中仅获取值而不是JSON响应中的键和值

Posted

技术标签:

【中文标题】在spring boot中仅获取值而不是JSON响应中的键和值【英文标题】:Getting only values instead of keys and values in JSON response in spring boot 【发布时间】:2020-06-25 00:40:21 【问题描述】:

我正在尝试使用 SQL 查询从存储库中检索数据,但是当我尝试检索数据时,我在 JSON 响应中只获得了值而不是键和值。

我有以下课程

存储库

@Repository
public interface ReportingDataRepository extends CrudRepository<Task, String> 
  @Query(name = "task.getReportingData")
  List<Task> getReportingData(String startDate, String endDate);

控制器

@RequestMapping(path = "/api/startdate/enddate")
public TaskScores getScoresDataByDate(@PathVariable("startdate") String startDate,
                                    @PathVariable("enddate") String endDate) 
  return new TaskScores((reportingDataRepository.getReportingData(startDate, endDate)));


控制器内的包装类

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Data
public class TaskScores 
  List<Task> tasks;

实体

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Data

@NamedNativeQuery(
    name = "task.getReportingData",
    query = "SELECT sys.id as id, sys.name as sys, sys.eventtype, workflow_agg.subprocess_id "
            + "FROM daily_agg_counts_system_score as sys_agg "
            + "join system_eventtype as sys on sys_agg.system_id = sys.id "
            + "join system_subprocess_mapping sm on sys_agg.system_id = sm.system_id "
            + "join daily_agg_workflow_completion_score workflow_agg on sm.subprocess_id = workflow_agg.subprocess_id "
            + "join sub_process sp on sp.id = sm.subprocess_id "
            + "join process as p on p.id = sys.process_id "
            + "join flow on flow.id = p.flow_id "
            + "join program on program.id = flow.program_id "
            + "where sys_agg.datepst BETWEEN ?1 AND ?2 "
            + "order by program.id asc, p.flow_id asc, sp.id asc, sys_agg.system_id asc, sys_agg.datepst asc "
            + "limit 1"
    )

    public class Task implements Serializable
      @Column(name = "id")
      @Id
      private String id;

      @Column(name = "system")
      private String sys;

      @Column(name = "event_type")
      private String eventType;

      @ManyToOne(fetch = FetchType.LAZY)
      private SubProcess subprocessId;

      @Embeddable
      class Score implements Serializable 
      @JsonIgnore
      String score;
    
 

我正在使用 Spring Data JPA。当我运行这段代码时,我得到了以下 JSON 文件

"tasks": [ [ 1, "oms", "BE", 1 ] ]

但我希望它像实际的 json "tasks": [ [ "id" : 1, "sys" : "oms", "eventType" : "BE", "subprocessId" : 1 ] ]

知道我哪里出错了吗?

【问题讨论】:

【参考方案1】:

是的,您正在使用 本机查询,并且您正在尝试通过将查询结果与您的对象映射来将结果存储在对象中。不幸的是,它不能那样工作。

如果您尝试在 Object 中使用本机查询的结果,您将只能获取值而不是键和值。要同时获取键和值,您有两种选择:

一种方法是SQLResultsetMapping。 请参阅SQLResultsetMapping 了解更多信息。

另一种简单的方法是使用投影界面

首先在您的查询中更改这一行:

SELECT sys.id as id, sys.name as sys, sys.eventtype, workflow_agg.subprocess_id

SELECT sys.id as id, sys.name as sys, sys.eventtype as eventtype, workflow_agg.subprocess_id as subprocessid

即为您检索到的所有列提供别名。

然后你创建一个像这样的接口(这称为投影接口):

interface getSysProperties
    getid();
    getsys();
    geteventtype();
    getsubprocessid();

然后,不要在对象中检索 SQL 结果,而是在界面投影中检索它,例如:

  @Query(name = "task.getReportingData")
  List<getSysProperties> getReportingData(String startDate, String endDate);
        // ^Projection interface instead of Entity

如果您只想检索您的 SQL 数据,然后不想在您的代码中修改它,则此方法将有效。

【讨论】:

【参考方案2】:

在你的情况下,我会创建一个 TaskDto 类:

package your.package.dto;
@Data
@AllArgsConstructor
public class TaskDto implements Serializable  
    // all fields 

比,我会使用如下查询

SELECT new your.package.dto.TaskDto (sys.id, sys.name, sys.eventtype, workflow_agg.subprocess_id)
FROM ...

请注意:

    查询里面没有用到as; 查询不能通过native;

【讨论】:

以上是关于在spring boot中仅获取值而不是JSON响应中的键和值的主要内容,如果未能解决你的问题,请参考以下文章

在 API 响应中返回 Enum 的值而不是 Spring Boot 中的名称

Spring boot:仅访问 JPA 中的关联列值而不获取完整的关联实体

在 oracle apex 20 中仅显示表中显示来自 LOV 的显示值而不是 id

在grails中解析JSON时如何获取真正的空值而不是JSONObject.NULL值

Spring MongoDB 在结果中只获取值而不是 key:value

如何允许用户在 Spring Boot / Spring Security 中仅访问自己的数据?