Spring Data JPA 實現多表聯查的另一種方式
阿新 • • 發佈:2018-12-18
通過封裝實體類來實現多表聯查的方式,利用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(); }
到此打完收工!!!