DTO的作用,以建立訂單和訂單列表分頁為例
阿新 • • 發佈:2019-02-14
entity為了傳遞資訊增加@Transient修飾的屬性會汙染實體純淨
@Entity
@Data
@DynamicUpdate
public class OrderMaster {
/** 訂單id. */
@Id
private String orderId;
/** 買家名字. */
private String buyerName;
/** 買家手機號. */
private String buyerPhone;
/** 買家地址. */
private String buyerAddress;
/** 買家微信Openid. */
private String buyerOpenid;
/** 訂單總金額. */
private BigDecimal orderAmount;
/** 訂單狀態, 預設為0新下單. */
private Integer orderStatus = OrderStatusEnum.NEW.getCode();
/** 支付狀態, 預設為0未支付. */
private Integer payStatus = PayStatusEnum.WAIT.getCode();
/** 建立時間. */
private Date createTime;
/** 更新時間. */
private Date updateTime;
@Transient
private List<OrderDetail> orderDetailList;
}
訂單物件中放入訂單詳情列表會方便傳遞資訊,但造成訂單實體的不純潔,理論上應該和DB欄位一一對應
DTO 資料傳輸物件就是用來解決上面的問題
@Data
public class OrderDTO {
/** 訂單id. */
private String orderId;
/** 買家名字. */
private String buyerName;
/** 買家手機號. */
private String buyerPhone;
/** 買家地址. */
private String buyerAddress;
/** 買家微信Openid. */
private String buyerOpenid;
/** 訂單總金額. */
private BigDecimal orderAmount;
/** 訂單狀態, 預設為0新下單. */
private Integer orderStatus;
/** 支付狀態, 預設為0未支付. */
private Integer payStatus;
/** 建立時間. */
@JsonSerialize(using = Date2LongSerializer.class)
private Date createTime;
/** 更新時間. */
@JsonSerialize(using = Date2LongSerializer.class)
private Date updateTime;
List<OrderDetail> orderDetailList;
@JsonIgnore
public OrderStatusEnum getOrderStatusEnum() {
return EnumUtil.getByCode(orderStatus, OrderStatusEnum.class);
}
@JsonIgnore
public PayStatusEnum getPayStatusEnum() {
return EnumUtil.getByCode(payStatus, PayStatusEnum.class);
}
}
@Data
public class CartDTO {
/** 商品Id. */
private String productId;
/** 數量. */
private Integer productQuantity;
public CartDTO(String productId, Integer productQuantity) {
this.productId = productId;
this.productQuantity = productQuantity;
}
}
建立訂單中的dto與entity互動
POST /sell/buyer/order/create
引數
name: "張三"
phone: "18868822111"
address: "慕課網總部"
openid: "ew3euwhd7sjw9diwkq" //使用者的微信openid
items: [{
productId: "1423113435324",
productQuantity: 2 //購買數量
}]
@Override
@Transactional
public OrderDTO create(OrderDTO orderDTO) {
String orderId = KeyUtil.genUniqueKey();
BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
//1. 查詢商品(數量, 價格)
for (OrderDetail orderDetail: orderDTO.getOrderDetailList()) {
ProductInfo productInfo = productService.findOne(orderDetail.getProductId());
if (productInfo == null) {
throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
// throw new ResponseBankException();
}
//2. 計算訂單總價
orderAmount = productInfo.getProductPrice()
.multiply(new BigDecimal(orderDetail.getProductQuantity()))
.add(orderAmount);
//訂單詳情入庫
orderDetail.setDetailId(KeyUtil.genUniqueKey());
orderDetail.setOrderId(orderId);
BeanUtils.copyProperties(productInfo, orderDetail);
orderDetailRepository.save(orderDetail);
//此處不做扣庫存操作是為了功能純潔
// CartDTO cartDTO = new CartDTO(orderDetail.getProductId(), orderDetail.getProductQuantity());
// cartDTOList.add(cartDTO);
}
//3. 寫入訂單資料庫(orderMaster和orderDetail)
OrderMaster orderMaster = new OrderMaster();
//先在DTO完成賦值,然後再物件拷貝到entity,否則容易覆蓋
orderDTO.setOrderId(orderId);
BeanUtils.copyProperties(orderDTO, orderMaster);
orderMaster.setOrderAmount(orderAmount);
orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
orderMasterRepository.save(orderMaster);
//4. 扣庫存
List<CartDTO> cartDTOList = orderDTO.getOrderDetailList().stream().map(e ->
new CartDTO(e.getProductId(), e.getProductQuantity())
).collect(Collectors.toList());
productService.decreaseStock(cartDTOList);
//傳送websocket訊息
webSocket.sendMessage(orderDTO.getOrderId());
return orderDTO;
}
public class KeyUtil {
/**
* 生成唯一的主鍵
* 格式: 時間+隨機數
* @return
*/
public static synchronized String genUniqueKey() {
Random random = new Random();
Integer number = random.nextInt(900000) + 100000;
return System.currentTimeMillis() + String.valueOf(number);
}
}
訂單分頁列表
@Override
public Page<OrderDTO> findList(String buyerOpenid, Pageable pageable) {
Page<OrderMaster> orderMasterPage = orderMasterRepository.findByBuyerOpenid(buyerOpenid, pageable);
List<OrderDTO> orderDTOList = OrderMaster2OrderDTOConverter.convert(orderMasterPage.getContent());
return new PageImpl<OrderDTO>(orderDTOList, pageable, orderMasterPage.getTotalElements());
}
public class OrderMaster2OrderDTOConverter {
public static OrderDTO convert(OrderMaster orderMaster) {
OrderDTO orderDTO = new OrderDTO();
BeanUtils.copyProperties(orderMaster, orderDTO);
return orderDTO;
}
public static List<OrderDTO> convert(List<OrderMaster> orderMasterList) {
return orderMasterList.stream().map(e ->
convert(e)
).collect(Collectors.toList());
}
}