最近在對JPA的使用過程中發現對於單表的操作很是方便,但是當設計到多表聯查的時候就需要有一些特殊的操作了。
項目中有一個場景是後臺需要做一個分頁的列表查詢,所需要的數據分散在兩張表中,如果是用mybatis的話直接定義resultMap,然後手寫SQL就可以了。而在JPA中就需要用到JPQL了。
首先定義一下各個對象之間的關係
實體 GxOrderDO :訂單。
實體 GxOrderDetailDO:訂單詳情。
實體 GxOrderInfoRsp:分裝的分頁返回對象。
其中的GxOrderDO和GxOrderDetailDO通過orderId字段做兩張表的關聯。
創建一個對象用來封裝返回的結果集:
GxOrderInfoRsp.java:
public class GxOrderInfoRsp implements Serializable{
/**
* 訂單ID
*/
private String orderId;
/**
* 訂單狀態
*/
private Integer orderStatus;
/**
* 訂單類型
*/
private Integer orderType;
/**
* 訂單支付金額
*/
private BigDecimal orderAmount;
/**
* 訂單渠道(設備)類型
*/
private Integer orderChannel;
public GxOrderInfoRsp(String orderId, Integer orderStatus, Integer orderType,
BigDecimal orderAmount, Integer orderChannel) {
this.orderId = orderId;
this.orderStatus = orderStatus;
this.orderType = orderType;
this.orderAmount = orderAmount;
this.orderChannel = orderChannel;
}
Repository:
@Query("SELECT new com.app.domain.GxOrderInfoRsp(r.orderId, r.orderStatus, r.orderType, rd.orderAmount, rd.orderChannel) FROM GxOrderDO r, GxOrderDetailDO rd WHERE r.orderId = rd.orderId and ( r.orderId=:#{#customer.orderId} or :#{#customer.orderId} is null or :#{#customer.orderId} = '') ")
Page<GxOrderInfoRsp> findOrderPage(@Param("customer") GxOrderDO customer,Pageable pageable);
注意:@Query中new的對象的參數順序要和構造方法的參數順序一致
r.orderId=:#{#customer.orderId} or :#{#customer.orderId} is null)
這種是做個非空判斷,如果是空,就跳過這個條件,不執行。
這裏面用到了Spring Data JPA @Query定義中的SpEL特性
Service:
Pageable pageable = new PageRequest(0,3, Sort.Direction.DESC,"createTime");
文章參考:
https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions