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 where(String orderId, Integer orderType, String phone, List orderStatus, List applyStatus, List payStatus, String openId) {
        return new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                List predicates = new ArrayList();
                // 订单编号
                if (!StringUtils.isEmpty(orderId)) {
                    predicates.add(cb.equal(root. get("orderId"), orderId));
                }

                // 订单状态
                if (null != orderStatus && orderStatus.size() > 0) {
                    predicates.add(root. get("orderStatus").in(orderStatus));
                }

                // 申请状态
                if (null != applyStatus && applyStatus.size() > 0) {
                    predicates.add(root. get("applyStatus").in(applyStatus));
                }

                // 支付状态
                if (null != payStatus && payStatus.size() > 0) {
                    predicates.add(root. get("payStatus").in(payStatus));
                }

                // 补换卡类型
                if (null != orderType) {
                    predicates.add(cb.equal(root. get("orderType"), orderType));

                    // 补换的号码
                    if (!StringUtils.isEmpty(phone)) {
                        if(orderType == ReplaceCardConstant.ORDER_TYPE_CN){
                            //补换170卡号码
                            predicates.add(cb.equal(root. get("phoneCN"), phone));
                        } else if (orderType == ReplaceCardConstant.ORDER_TYPE_AU) {
                            //补换澳洲卡号码
                            predicates.add(cb.equal(root. get("phoneAU"), phone));
                        }
                    }
                }

                // 补换卡用户
                if (!StringUtils.isEmpty(openId)) {
                    predicates.add(cb.equal(root. 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 where = where(orderId, orderType, phone, orderStatus, applyStatus, payStatus, openId);

//通过条件查询补换卡订单详情
List rest = replaceCardOrderDao.findAll(where);

你可能感兴趣的:(spring-data-jpa)