电商项目——CG
为何使用分布式ID项目中如何使用分布式ID搞清SPU和SKU的区别商品的CRUD增加商品根据id查询商品修改商品审核商品商品上下架删除商品全局异常处理
为何使用分布式ID
我们学过UUID是唯一的,但是它是字符串,查询效率低。无法保证递增的趋势,不可读。也可用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现,但是网络传输会造成性能下降。而雪花算法(snowflake)的其核心思想是:使用前41bit作为毫秒数,中间10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),后12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最前还有一个符号位,永远是0(二进制1为负数)。几乎完美解决了上述的问题。
项目中如何使用分布式ID
首先引入工具包IdWorker.javachanggou_service_goods中yml配置:这两值只能在0~31之间
workerId: 0
datacenterId: 0
在启动类配置一个idWorker的Bean,以@Value将两个属性注进来。
搞清SPU和SKU的区别
概念 SPU:一个统称 SKU:对SPU的细化,比如有颜色,内存大小等等就搞一个SKU不行吗? 答案是:不行,因为对于单个商品(如小米10)的详情,图片,友情链接是一样的。SPU更加便于维护。
商品的CRUD
增加商品
商品Goods由spu和sku组成,所以在…-api中先创建Goods实体类spu业务层新增方法add(Goods goods),先存spu,再存sku。具体逻辑: - 生成分布式ID,重新封装spu(审核状态,删除状态,上架状态全为0),再调用方法spuMapper.insertSelective(spu)进行保存。 - 存sku的时候注意两点,第一:分类与品牌的关联,如未建立则需在tb_category_brand添加数据,方便数据的维护。第二:skuList中拿到的spec是个json字符串,需要将其拿出来转成map取value的值再与name组合生成最终的name。再重新封装sku,向表中添加数据。sku所需数据如下:
private String sn
;
private String name
;
private Integer price
;
private Integer num
;
private Integer alertNum
;
private String image
;
private String images
;
private Integer weight
;
private java
.util
.Date createTime
;
private java
.util
.Date updateTime
;
private String spuId
;
private Integer categoryId
;
private String categoryName
;
private String brandName
;
private String spec
;
private Integer saleNum
;
private Integer commentNum
;
private String status
;
根据id查询商品
根据id查询spu。封装Example对象,然后根据id查询出所有的skuList。创建Goods对象,将spu和skuList一起放进对象中并返回。
修改商品
首先从goods中拿到spu,对spu进行修改根据spu的id删除所有的sku,再重新增加(调用新增方法)
审核商品
分析: 先通过id查询到spu,如果spu为空或者删除状态为1,则抛一个系统异常(本篇的最后),否则就将spu的status和isMarketable设为1。代码如下:
@Transactional
@Override
public void audit(String id
) {
Spu spu
= spuMapper
.selectByPrimaryKey(id
);
if (spu
==null
|| "1".equals(spu
.getIsDelete())){
throw new BusinessException(new Result(false, StatusCode
.ERROR
,"无此商品信息或处于删除状态"));
}
spu
.setStatus("1");
spu
.setIsMarketable("1");
spuMapper
.updateByPrimaryKeySelective(spu
);
}
商品上下架
分析: 无论上下架都要先进行判断,根据id查询spu,若spu为空或者处于删除状态,或status为0都不可操作,抛一个系统异常。否则直接更改上架状态,代码简单,不做赘述。
删除商品
逻辑删除(可还原) 先做一个判断,未下架商品不能逻辑删除,下架后可直接更改删除状态为1。 还原商品:当status为0或删除状态为0都不可操作,否则直接修改删除状态为0。物理删除 根据id直接删除数据即可。
全局异常处理
主要利用了Aop思想,做了异常捕获类,代码如下:
@ControllerAdvice
public class BaseExceptionHandler {
@ExceptionHandler(value
= BusinessException
.class)
@ResponseBody
public Result
otherError(BusinessException e
){
e
.printStackTrace();
return e
.getResult();
}
@ExceptionHandler(value
= Exception
.class)
@ResponseBody
public Result
error(Exception e
){
e
.printStackTrace();
return new Result(false, StatusCode
.ERROR
, "执行出错");
}
}