1. 程式人生 > >Spring data JPA使用Specification實現動態查詢例子

Spring data JPA使用Specification實現動態查詢例子

實體類

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);