Spring Boot Jpa框架自定義查詢語句返回自定義實體


開始的想法源於netcore中通過lambd查詢數據庫后可以直接轉為實體,所以試驗在java中如何實現

具體試驗思路:

利用現有數據庫,定義一個獲取車輛的api,調用獲取車輛及司機信息

1、現有車輛和司機模型

車輛表(大概列一下,實際比這多):

@Entity
@Data
@Table(name="car")
public class Car implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    /** 車牌號 */
    @ApiModelProperty("車牌號")
    @Column(name = "car_number",nullable = false)
    private String carNumber;


    /** 車輛容積 */
    @ApiModelProperty("最大載量")
    @Column(name = "car_volume",nullable = false)
    private Double carVolume;


    /** 燃料類型 */
    @ApiModelProperty("燃料類型")
    @Column(name = "fuel_type")
    private String fuelType;

    /** 百公里耗能 */
    @ApiModelProperty("百公里耗能")
    @Column(name = "energy_consumption")
    private Double energyConsumption;


    /** 車輛營運狀態 */
    @ApiModelProperty("車輛狀態")
    @Column(name = "car_operating_state")
    private Integer carOperatingState;

    /** 車輛狀態 */
    @ApiModelProperty("車輛營運狀態")
    @Column(name = "car_status",nullable = false)
    private Integer carStatus;
}

司機表

@Entity
@Data
@Table(name="driver")
public class Driver implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    /** 姓名 */
    @ApiModelProperty("姓名")
    @Column(name = "name",nullable = false)
    @NotBlank
    private String name;

    /** 性別 */
    @ApiModelProperty("性別")
    @Column(name = "sex")
    private Integer sex;

    /** 年齡 */
    @ApiModelProperty("年齡")
    @Column(name = "age")
    private Integer age;

    /** 生日 */
    @ApiModelProperty("生日")
    @Column(name = "birthday")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date birthday;

    /** 手機號 */
    @ApiModelProperty("手機號")
    @Column(name = "phone")
    private String phone;


    public void copy(Driver source){
        BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
    }
}

2、定義返回模型

最終返回

@Data
public class CarAndUnitTest {

    public CarAndUnitTest_Car<CarAndDriverTest> car;
}
@Data
public class CarAndUnitTest_Car<T> {
    public Integer all;
    public Integer working;
    public Integer alarm;
    public List<T> list;
}
@Data
public class CarAndDriverTest extends CarAndDriverTestBase {
    //車輛狀態值
    private String carStatusStr;
}
@Data
public class CarAndDriverTestBase {
    private Integer id;
    //車牌號
    private String car_number;

    //最大載量
    private Double car_volume;
    //車輛狀態
    private Integer car_status;
    //司機ID
    private Integer driver_id;
    //司機電話
    private String phone;
    //司機名稱
    private String name;

    public CarAndDriverTestBase(Integer id,String car_number,Double car_volume,Integer car_status,Integer driver_id,String phone,String name){
        this.id=id;
        this.car_number=car_number;
        this.car_volume=car_volume;
        this.car_status=car_status;
        this.driver_id=driver_id;
        this.phone=phone;
        this.name=name;
    }

    public CarAndDriverTestBase() {
    }
}

3、定義入參模型(這個不重要)

@Data
public class QueryPara {
//    @ApiModelProperty("操作標識,1為選擇機組車輛時的帶條件選擇,其他為不帶條件的查詢,可為空")
//    private int operFlag;

    @ApiModelProperty("品類名稱,操作標識為1的時候不能為空,品類名稱從任務單中獲得")
    private String procCate;

}

4、定義服務

@ApiOperation("查詢車輛和機組信息1")
    @PostMapping(value = "/getCarAndUnitTest")
    /*
        operFlag:操作標識 , proCategory:產品分類
     */
    public CarAndUnitTest getCarAndUnitTest(@RequestBody QueryPara query) {

        return carService.getCarAndUnit_1(query);
    }

5、業務實現

public CarAndUnitTest getCarAndUnit_1(QueryPara query){

        CarAndUnitTest r=new CarAndUnitTest();

        CarAndUnitTest_Car car= CarList(query);
        r.car=car;

        return  r;
    }

    //獲取車
    private CarAndUnitTest_Car CarList(QueryPara query){

        CarAndUnitTest_Car r=new CarAndUnitTest_Car();
        List<CarAndDriverTest> list=allCar();
        r.list=list;
        r.all=list.size();
        r.working=0;
        r.alarm=0;
        return  r;
    }

    //所有車
    private  List<CarAndDriverTest> allCar(){
        List<CarAndDriverTest> list= new ArrayList<>();

        List<CarAndDriverTestBase> caranddriverlist=carRepository.allCarAndDriverTest();

        for(CarAndDriverTestBase obj:caranddriverlist){

            CarAndDriverTest add=new CarAndDriverTest();
            add.setId(obj.getId());
            add.setCar_status(obj.getCar_status());
            add.setCar_number(obj.getCar_number());
            add.setCar_volume(obj.getCar_volume());
            add.setDriver_id(obj.getDriver_id());

            add.setName(obj.getName());
            add.setPhone(obj.getPhone());
            add.setCarStatusStr(CarStatus.getName(obj.getCar_status()));

            list.add(add);
        }
        return list;
    }

6、數據查詢

@Query(value="select new me.zhengjie.scheduling.car.domain.CarAndDriverTestBase( c.id,c.carNumber,c.carVolume,c.carStatus,c.driverId,d.phone,d.name) "+
            "FROM Car c LEFT JOIN Driver d ON c.driverId = d.id where c.flag = 1",nativeQuery = false)
    List<CarAndDriverTestBase> allCarAndDriverTest();

7、最終結果

 

 

 

記錄細節,踩坑

主要是這個

@Query(value="select new me.zhengjie.scheduling.car.domain.CarAndDriverTestBase( c.id,c.carNumber,c.carVolume,c.carStatus,c.driverId,d.phone,d.name) "+
            "FROM Car c LEFT JOIN Driver d ON c.driverId = d.id where c.flag = 1",nativeQuery = false)
    List<CarAndDriverTestBase> allCarAndDriverTest();
CarAndDriverTestBase:是我們查詢結果需要轉換的實體
nativeQuery:false 或者nativeQuery不賦值,默認false.如果賦值true的話前面的value值是原生sql語句
new me.zhengjie.scheduling.car.domain.CarAndDriverTestBase( c.id,c.carNumber,c.carVolume,c.carStatus,c.driverId,d.phone,d.name):
我理解就是查詢結果的每條數據通過調用實體的構造函數來賦值,但是又找不到實體在哪,干脆把路徑補全

 

 注意構造函數的參數順序

 

 還要注意實體的數據類型要和表實體的數據類型一致,名字可以不一樣

 

 

 

 最后一點

FROM Car c LEFT JOIN Driver d ON c.driverId = d.id where c.flag = 1
其中的Car和Driver用的是表實體的name

 

最最重要的: 

1、查詢語句中使用表實體名稱

2、CarAndDriverTestBase中屬性的數據類型一定要和表實體屬性的數據類型一致


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM