springboot秒杀课程学习整理1-5
1)交易模型设计
交易模型(用户下单的交易模型)OrderModel
id(String 交易单号使用String), userId,itemId,amount(数量),orderAmount(总金额), itemPrice(购买时的价格)
创建表order_info
id,userId,item_id,item_price,amount,order_amount
2)使用mybatis-generator生成对应的文件
3)生成订单的流程
1)校验商品是否存在,用户是否合法,购买数量是否正确
2)落单减库存(需要在ItemServiceImpl里添加方法用户更新库存数量,这里需要添加sql语句更新库存)
3) 生成订单(订单有一定的规则:这里是16位,由时间,自增序列,分库分表组成)
4)订单入库
5)添加销量(需要在itemServiceImpl里添加方法更新销量,并且需要新增sql语句)
OrderModel
package com.miaoshaproject.service.model; import java.math.BigDecimal; public class OrderModel { private String id; private Integer userId; private Integer itemId; private Integer amount; private BigDecimal orderAmount; private BigDecimal itemPrice; public String getId() { return id; } public void setId(String id) { this.id = id; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public Integer getItemId() { return itemId; } public void setItemId(Integer itemId) { this.itemId = itemId; } public Integer getAmount() { return amount; } public void setAmount(Integer amount) { this.amount = amount; } public BigDecimal getOrderAmount() { return orderAmount; } public void setOrderAmount(BigDecimal orderAmount) { this.orderAmount = orderAmount; } public BigDecimal getItemPrice() { return itemPrice; } public void setItemPrice(BigDecimal itemPrice) { this.itemPrice = itemPrice; } }
OrderService
package com.miaoshaproject.service; import com.miaoshaproject.error.BusinessException; import com.miaoshaproject.service.model.OrderModel; public interface OrderService { OrderModel createModel(Integer userId, Integer itemId, Integer amount) throws BusinessException; }
OrderServiceIpml
package com.miaoshaproject.service.impl; import com.miaoshaproject.dao.ItemDOMapper; import com.miaoshaproject.dao.OrderDOMapper; import com.miaoshaproject.dao.SequenceDOMapper; import com.miaoshaproject.dao.UserDOMapper; import com.miaoshaproject.dataobject.ItemDO; import com.miaoshaproject.dataobject.OrderDO; import com.miaoshaproject.dataobject.SequenceDO; import com.miaoshaproject.dataobject.UserDO; import com.miaoshaproject.error.BusinessException; import com.miaoshaproject.error.EmBusinessError; import com.miaoshaproject.service.OrderService; import com.miaoshaproject.service.model.ItemModel; import com.miaoshaproject.service.model.OrderModel; import com.miaoshaproject.service.model.UserModel; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; @Service public class OrderServiceImpl implements OrderService { @Autowired private ItemServiceImpl itemService; @Autowired private UserServiceImpl userService; @Autowired private ItemDOMapper itemDOMapper; @Autowired private UserDOMapper userDOMapper; @Autowired private OrderDOMapper orderDOMapper; @Autowired private SequenceDOMapper sequenceDOMapper; @Override @Transactional //保证订单是在同一事务当中? public OrderModel createModel(Integer userId, Integer itemId, Integer amount) throws BusinessException { //1校验下单状态,下单的商品是否存在,用户是否合法,购买数量是否正确 ItemModel itemModel = itemService.getItemById(itemId); if(itemModel == null){ throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"商品信息不存在"); } UserModel userModel =userService.getUserById(userId); if(userModel == null){ throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"用户不存在"); } if(amount<=0 || amount>99){ throw new BusinessException(EmBusinessError.PARAMTER_VALIDATION_ERROR,"商品数量不正确"); } //2.落单减库存 boolean result =itemService.decreaseStock(itemId,amount); if(!result){ throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH); } //3.订单入库 OrderModel orderModel = new OrderModel(); orderModel.setUserId(userId); orderModel.setItemId(itemId); orderModel.setAmount(amount); orderModel.setItemPrice(itemModel.getPrice()); orderModel.setOrderAmount(itemModel.getPrice().multiply(new BigDecimal(amount))); //生成订单号 orderModel.setId(generatorOrderNo()); OrderDO orderDO=this.convertOrderDOFromOrderModel(orderModel); orderDOMapper.insertSelective(orderDO); //加上销售额 itemService.increaseSales(itemId,amount); //返回前端 return orderModel; } public OrderDO convertOrderDOFromOrderModel(OrderModel orderModel){ OrderDO orderDO = new OrderDO(); if(orderModel == null){ return null; } BeanUtils.copyProperties(orderModel,orderDO); orderDO.setItemPrice(orderModel.getItemPrice().doubleValue()); orderDO.setOrderAmount(orderModel.getOrderAmount().doubleValue()); return orderDO; } @Transactional(propagation = Propagation.REQUIRES_NEW) public String generatorOrderNo(){ //订单号有16 StringBuilder stringBuilder = new StringBuilder(); // 前8位是时间年月日 LocalDateTime now = LocalDateTime.now(); String nowDate = now.format(DateTimeFormatter.ISO_DATE).replace("-",""); stringBuilder.append(nowDate); //中间6位是自增序列, // 创建sequence_info表有字段name current_value step //每次加step,然后更新表,不够6位用0补上 int sequence = 0; SequenceDO sequenceDO = sequenceDOMapper.getSequenceByName("order_info"); sequence = sequenceDO.getCurrentValue(); sequenceDO.setCurrentValue(sequenceDO.getCurrentValue()+sequenceDO.getStep()); sequenceDOMapper.updateByPrimaryKey(sequenceDO); String sequenceStr = String.valueOf(sequence); for(int i=0;i<6 - sequenceStr.length(); i++){ //这里需要考虑的一点是如果大于6的 // 时候怎么处理 stringBuilder.append(0); } stringBuilder.append(sequenceStr); //最后两位是分库分表位,这里而写死 stringBuilder.append("00"); return stringBuilder.toString(); } }
OrderController
package com.miaoshaproject.controller; import com.miaoshaproject.error.BusinessException; import com.miaoshaproject.error.EmBusinessError; import com.miaoshaproject.response.CommonReturnType; import com.miaoshaproject.service.impl.OrderServiceImpl; import com.miaoshaproject.service.model.OrderModel; import com.miaoshaproject.service.model.UserModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; @RestController @RequestMapping("/order") @CrossOrigin(allowCredentials = "true",allowedHeaders = "*") public class OrderController extends BaseController{ @Autowired private HttpServletRequest httpServletRequest; @Autowired private OrderServiceImpl orderService; @RequestMapping(value="create",method = RequestMethod.POST,consumes = {CONTENT_TYPE_FORMED}) public CommonReturnType createOrder (@RequestParam(name="itemId")Integer itemId, @RequestParam(name="amount")Integer amount ) throws BusinessException { Boolean isLogin = (Boolean)httpServletRequest.getSession().getAttribute("IS_LOGIN"); if(isLogin == null||!isLogin.booleanValue()){ throw new BusinessException(EmBusinessError.USER_NOT_LOGIN,"用户还未登入不能下单"); } UserModel userModel=(UserModel) httpServletRequest.getSession().getAttribute("LOGIN_USER"); //进行下单操作 OrderModel orderModel=orderService.createModel(userModel.getId(),itemId,amount); return CommonReturnType.create(null); } }