跨多个表的 JPA 本机查询

hoo*_*dhi 6 jpa spring-data-jpa

我将以下内容定义为存储库 (dispenseRepository) 中的本机查询:

@Query(
        value = "SELECT p.*, c.*, s.*, d.* from patient p, consult c ,script s,dispense d "
                + " where p.patient_id=c.patient_id "
                + " and c.consult_id = d.consult_id " 
                + " and c.fk_script_id =s.script_id"
                + " and c.consult_id=?1 ", 
        nativeQuery = true
)
List<Dispense> findInvoiceByConsultId(Long consultId);
Run Code Online (Sandbox Code Playgroud)

其余控制器有:

  @RequestMapping(value = "/api/invoice/{consultId}",method = {RequestMethod.GET}) 
    public List<Dispense> invoice(@PathVariable(value="consultId")Long consultId){
       return dispenseRepository.findInvoiceByConsultId(consultId);
    }
Run Code Online (Sandbox Code Playgroud)

当我点击 api 时,我只得到分配详细信息:

[
{
    "dispenseId": 1,
    "icd10": "J.10",
    "tariffCode": "10010",
    "dispenseItem": "Lenses",
    "price": 400.0
},
{
    "dispenseId": 3,
    "icd10": "J.10",
    "tariffCode": "111000",
    "dispenseItem": "Other",
    "price": 1500.0
},
{
    "dispenseId": 4,
    "icd10": "K.100",
    "tariffCode": "10010",
    "dispenseItem": "Eye Test",
    "price": 550.0
}
Run Code Online (Sandbox Code Playgroud)

]

我想要按照查询提供的所有数据,这些数据将用于 Jasper 报告

ERD

patient-consult 1-M

consult-script 1-1

consult-dispense 1-M
Run Code Online (Sandbox Code Playgroud)

ple*_*eft 7

由于在查询中返回所有表中的所有字段:SELECT p.*, c.*, s.*, d.* from patient p, consult c ,script s,dispense d 为如此多的对象和字段创建投影/DTO 非常麻烦。有 2 种方法可以继续。要么准确指定查询中每个表中所需的字段,然后创建 DTO 来保存这些字段。例如

方法一:

我只从每个表中选择一个字段作为示例。请注意,您必须将查询从本机查询转换为 jpa 查询!

@Query("SELECT new com.example.demo.ResultDTO(p.patientName, c.reservationNumber, s.addition, d.dispenseItem) from Patient p, Consult c, Script s, Dispense d ...")
List<ResultDTO> findInvoiceByConsultId(Long consultId);
Run Code Online (Sandbox Code Playgroud)

ResultDTO可以是:

package com.example.demo;

public class ResultDTO {

    private String patientName;
    private String reservationNumber;
    private String addition;
    private String dispenseItem;

    public ResultDTO(String patientName, String reservationNumber, String addition, String dispenseItem) {
        this.patientName = patientName;
        this.reservationNumber = reservationNumber;
        this.addition = addition;
        this.dispenseItem = dispenseItem;
    }

    public String getPatientName() {
        return patientName;
    }

    public void setPatientName(String patientName) {
        this.patientName = patientName;
    }

    public String getReservationNumber() {
        return reservationNumber;
    }

    public void setReservationNumber(String reservationNumber) {
        this.reservationNumber = reservationNumber;
    }

    public String getAddition() {
        return addition;
    }

    public void setAddition(String addition) {
        this.addition = addition;
    }

    public String getDispenseItem() {
        return dispenseItem;
    }

    public void setDispenseItem(String dispenseItem) {
        this.dispenseItem = dispenseItem;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新 方法 1 不适用于 a nativeQuery,您必须将其转换为 jpa ,因此除非您将查询转换为 jpql ,否则上述代码将无法工作。

或者更简单但更庞大,保持查询不变并将结果放在 a Listof Maps 上。

方法2:

@Query(
        value = "SELECT p.*, c.*, s.*, d.* from patient p, consult c ,script s,dispense d "
                + " where p.patient_id=c.patient_id "
                + " and c.consult_id = d.consult_id " 
                + " and c.fk_script_id =s.script_id"
                + " and c.consult_id=?1 ", 
        nativeQuery = true
)
List<Map<String, Object>>  findInvoiceByConsultId(Long consultId);
Run Code Online (Sandbox Code Playgroud)