Spring data JPA使用Specification實現動態查詢例子
阿新 • • 發佈:2019-01-06
實體類
package com.net263.domain;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* 補換卡訂單表
*
* @author 李關欽
* @parameter
* @date 2016年12月1日 上午11:13:21
* @return
*/
@Entity
public class ReplaceCardOrder {
@Id
@GeneratedValue
private int id;
private Date createTime;
private Date modifyTime;
private String orderId; // 訂單編號
private String prepayId;// 微信預支付訂單號
private String transactionId;// 微信支付訂單號
private int orderType; // 補換卡型別:0-補換170卡,1-補換澳洲卡
private int orderStatus; // 訂單狀態:0-未付款,1-已付款,2-退款中,3-已退款 4-已撤單
private int applyStatus;// 申請狀態:0-未提交申請(未完成支付),1-申請已提交(已完成支付),2-補換卡處理中,3-已完成
private String openId;// 補換卡使用者
private String operateOpenId;// 操作人
// private String certificateNum; // 身份證號碼
@Column(name = "phone_CN")
private String phoneCN; // 補換的卡號:170
@Column(name = "phone_AU")
private String phoneAU; // 補換的卡號:澳洲
private String payWay; // 支付方式:免費-free;微信支付-wxPay;crm餘額支付-crmBalance
private BigDecimal rate;// 匯率
private int payStatus;// 支付狀態:0-未支付;1-已支付;2-支付失敗
private BigDecimal prepayPrice; // 售價-澳元
private int expressPayType;// 快遞費支付方式:0-到付;1-線上支付
private BigDecimal expressPrice; // 快遞費-澳元
private BigDecimal payPrice; // 支付金額-澳元(手續費+快遞費)
@Column(name = "pay_price_CNY")
private BigDecimal payPriceCNY;// 支付金額-人民幣(手續費+快遞費)
private int shippingStatus; // 物流狀態:0-未發貨,1-已發貨,2-已簽收,3-問題件
private String iccid; // 新卡的iccid
private String imsi; // 新卡的imsi
private int recvAddressType;// 收貨地址型別:0-中國;1-澳洲
private String recvProvince; // 收貨省份(澳洲:具體地址)
private String recvCity; // 收貨城市(澳洲:市郊)
private String recvRegion; // 收貨區縣(澳洲:州)
private String recvDetail; // 收貨詳細地址(澳洲-郵編)
private String recvPhone; // 收貨人電話
private String recvName; // 收貨人姓名
private int recvMethod; // sim卡提取方式:0-郵寄,1-機場自提
private String recvAddress; // 收貨人地址(中國:省、市、區、詳細地址通過下劃線拼接;澳洲:地址、市郊、州、郵編通過下劃線拼接)
private String logisticsNo; // 物流單號
private String logisticsInfo; // 物流資訊
private String expressCom; // 快遞公司名稱
private BigDecimal refundPrice; // 退款金額
private String airportInfo; // 機場資訊
private String remark;// 備註資訊
private Integer accountId;
// private String passName;//護照 名字
// private String passXing;//護照姓氏
// private String passNum;// 護照號碼
private String productId;// 產品id
//省略 getter、setter 方法
}
serviceImpl的動態條件的方法
/**
* 條件查詢補換卡訂單列表時的動態組裝條件
*
* @param orderId 訂單編號
* @param orderType 補換卡型別:0-補換170卡,1-補換澳洲卡
* @param phone 補換的號碼:當orderType為0時為170號碼,當orderType為1時為澳洲號碼
* @param orderStatus 訂單狀態:0-未付款,1-已付款,2-退款中,3-已退款 4-已撤單
* @param applyStatus 申請狀態:0-未提交申請(未完成支付),1-申請已提交待處理(已完成支付),2-補換卡處理中,3-已完成,4-申請已取消
* @param payStatus 支付狀態:0-未支付;1-已支付;2-支付失敗
* @param openId 補換卡使用者
* @return
*/
private Specification<ReplaceCardOrder> where(String orderId, Integer orderType, String phone, List<Integer> orderStatus, List<Integer> applyStatus, List<Integer> payStatus, String openId) {
return new Specification<ReplaceCardOrder>() {
@Override
public Predicate toPredicate(Root<ReplaceCardOrder> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
// 訂單編號
if (!StringUtils.isEmpty(orderId)) {
predicates.add(cb.equal(root.<String> get("orderId"), orderId));
}
// 訂單狀態
if (null != orderStatus && orderStatus.size() > 0) {
predicates.add(root.<Integer> get("orderStatus").in(orderStatus));
}
// 申請狀態
if (null != applyStatus && applyStatus.size() > 0) {
predicates.add(root.<Integer> get("applyStatus").in(applyStatus));
}
// 支付狀態
if (null != payStatus && payStatus.size() > 0) {
predicates.add(root.<Integer> get("payStatus").in(payStatus));
}
// 補換卡型別
if (null != orderType) {
predicates.add(cb.equal(root.<Integer> get("orderType"), orderType));
// 補換的號碼
if (!StringUtils.isEmpty(phone)) {
if(orderType == ReplaceCardConstant.ORDER_TYPE_CN){
//補換170卡號碼
predicates.add(cb.equal(root.<String> get("phoneCN"), phone));
} else if (orderType == ReplaceCardConstant.ORDER_TYPE_AU) {
//補換澳洲卡號碼
predicates.add(cb.equal(root.<String> get("phoneAU"), phone));
}
}
}
// 補換卡使用者
if (!StringUtils.isEmpty(openId)) {
predicates.add(cb.equal(root.<String> get("openId"), openId));
}
return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
}
};
}
DAO中使用動態條件
在DAO介面繼承JpaSpecificationExecutor介面,直接在DAO方法中傳入前面生成的where方法即可。
package com.net263.dao;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.net263.domain.ReplaceCardOrder;
/**
* @author 李關欽
* @parameter
* @date 2016年12月1日 下午2:22:57
* @return
*/
@Repository
public interface ReplaceCardOrderDao extends CrudRepository<ReplaceCardOrder, Integer>, JpaSpecificationExecutor<ReplaceCardOrder> {
}
在JpaSpecificationExecutor中已經存在了List findAll(Specification spec) 方法的
在serviceImpl中呼叫DAO中的方法
//條件查詢補換卡訂單列表時的動態組裝條件
Specification<ReplaceCardOrder> where = where(orderId, orderType, phone, orderStatus, applyStatus, payStatus, openId);
//通過條件查詢補換卡訂單詳情
List<ReplaceCardOrder> rest = replaceCardOrderDao.findAll(where);