您的位置:首页 > 编程语言 > Java开发

Spring data JPA使用Specification实现动态查询例子

2017-05-22 16:03 861 查看

实体类

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jpa spring spring-boot