1. 程式人生 > >Spring Data JPA 實現多表聯查的另一種方式

Spring Data JPA 實現多表聯查的另一種方式

       通過封裝實體類來實現多表聯查的方式,利用Spring Data JPA @Query定義中的SpEL中的

( rd.orderId=:#{#orderPageReq.orderId} or :#{#orderPageReq.orderId} is null)

等特性,可以滿足一些基本的查詢需求,但是對於一些特殊情況,比如當我們需要根據訂單支付金額是否等於0,這時存在三個查詢條件1:全部,2:等於0,3:不等於0,對於這種情況簡單的利用SpEL規則就不能滿足我們的需求了。

以訂單(order)和訂單詳情(orderDetail)兩張表作為關聯查詢,兩張表中的order.orderId和orderDetail.orderId存在對應關係,但是沒有設外來鍵。

一、首先在資料庫中建立檢視:

CREATE VIEW `view_gx_order_info` AS SELECT
`tbl_gx_order`.`order_id` AS `order_id`,
        `tbl_gx_order`.`complaint_state` AS `complaint_state`,
        `tbl_gx_order`.`create_time` AS `create_time`,
        `tbl_gx_order`.`order_amount` AS `order_amount`,
        `tbl_gx_order_detail`.`device_id` AS `device_id`,
        `tbl_gx_order_detail`.`discount_amount` AS `discount_amount`
FROM
        (
                `tbl_gx_order`
                JOIN `tbl_gx_order_detail` ON (
                (
                `tbl_gx_order`.`order_id` = `tbl_gx_order_detail`.`order_id`
        )
)
        )

二、建立檢視的對映物件:

import lombok.Data;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Subselect;

import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author ; dongdongqiang
 * @Description 訂單詳情檢視
 * @Date 2018/10/30
 */
@Data
@Entity
@Immutable
@Subselect("select * from view_gx_order_info")
public class GxOrderInfoDO implements Serializable{
    private static final long serialVersionUID = -1480564219055635362L;

    @Id
    private String orderId;
    /**
     * 投訴狀態
     *
     * @return
     */
    private Integer complaintState;
    /**
     *
     * 訂單建立時間
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;
    /**
     * 訂單支付金額
     */
    private BigDecimal orderAmount;
    /**
     * 裝置的ID
     */
    private String deviceId;
    /**
     * 優惠金額
     */
    private BigDecimal discountAmount;

}

三、建立Repository類

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/** * @author ; dongdongqiang 
 * @Description 訂單詳情檢視 
 * @Date 2018/10/30 
 */

public interface GxOrderInfoRepository extends JpaRepository<GxOrderInfoDO, String>,JpaSpecificationExecutor<GxOrderInfoDO> {

}

四、Service

此時的GxOrderInfoRepository與其他的表查詢介面的用法就是一樣的了。

@Override
public List test(OrderDetailReq gxOrderInfoDO) {
    Page<GxOrderInfoDO> page = gxOrderInfoRepository.findAll((root, cq, cb) -> {
        Predicate predicate = cb.conjunction();
        List<Expression<Boolean>> expressions = predicate.getExpressions();
        if (!StringUtils.isEmpty(gxOrderInfoDO.getUserId())) {
            expressions.add(cb.equal(root.get("userId"), gxOrderInfoDO.getUserId()));
        }
        if (!StringUtils.isEmpty(gxOrderInfoDO.getOrderId())) {
            expressions.add(cb.equal(root.get("orderId"), gxOrderInfoDO.getOrderId()));
        }
        return predicate;
    }, new PageRequest(0, 20, Sort.Direction.DESC, "createTime")));
    return page.getContent();
}

到此打完收工!!!