SpringBoot实战电商项目mall(30k+star)地址:github.com/macrozheng/…前端
原来的商品SKU设计存在着两个问题,一个是SKU表设计上面比较固化,没法扩展。另外一个是当修改了商品信息以后,商品SKU的ID会发生变化,因为购物车表和订单商品表都关联了商品SKU的ID,这样就会致使匹配不上。最近对这两个问题作了点优化,下面来聊聊优化的思路。java
首先咱们来了解下商品SPU和SKU的概念,可能不少没有接触过电商的朋友都不了解。git
举个例子:好比说如今有个手机商品叫小米8,小米8有不一样的属性,好比有它有黑色和蓝色的,有32G和64G版本的。此时小米8
就是一个SPU,而小米8黑色64G
就是一个SKU。github
商品的SKU信息是存储在pms_sku_stock
表中的,使用sp一、sp二、sp3这三个属性来存储商品的销售属性,这样作很不灵活,也难以扩展。数据库
这种作法也带来了后续的问题,好比咱们的购物车和订单都会须要存储销售属性,这样的话都会须要添加sp一、sp二、sp3的属性。json
因为商品的销售属性是动态的,无法肯定到底有多少个,此时咱们能够改用JSON格式来存储,在pms_sku_stock
表中添加了sp_data
字段。数组
sp_data
存储的就是一个JSON数组,好比颜色为黑色,容量为32G的手机存储信息以下。app
[
{
"key": "颜色",
"value": "黑色"
},
{
"key": "容量",
"value": "32G"
}
]
复制代码
这样修改之后,在原来的购物车表oms_cart_item
和订单商品表oms_order_item
中就均可以用JSON格式来存储销售属性了,使用的是product_attr
字段。ide
商品的SKU信息做为商品的关联信息,在修改商品信息时会同时进行修改。之前的作法是直接删除该商品的全部SKU信息,再从新添加。这样就会致使商品SKU中的ID被修改,因为在购物车和订单商品中关联了商品SKU的ID,就会致使原来的ID失效的问题。下面是原来修改商品中SKU信息的代码。学习
/** * 商品管理Service实现类 * Created by macro on 2018/4/26. */
@Service
public class PmsProductServiceImpl implements PmsProductService {
@Override
public int update(Long id, PmsProductParam productParam) {
//省略若干代码...
//删除该商品关联的SKU
PmsSkuStockExample skuStockExample = new PmsSkuStockExample();
skuStockExample.createCriteria().andProductIdEqualTo(id);
skuStockMapper.deleteByExample(skuStockExample);
handleSkuStockCode(productParam.getSkuStockList(),id);
//插入传入的全部SKU
relateAndInsertList(skuStockDao, productParam.getSkuStockList(), id);
}
}
复制代码
首先咱们须要和前端约定下,新增的商品SKU信息不传ID,要修改的商品SKU信息传ID,删除的直接不传SKU信息。而后咱们能够根据传入的SKU信息来肯定须要新增、修改、删除的SKU信息,这样就能够作到在更新商品SKU信息时,不改变原来商品SKU的ID了,具体流程以下。
具体代码实现以下:
/** * 商品管理Service实现类 * Created by macro on 2018/4/26. */
@Service
public class PmsProductServiceImpl implements PmsProductService {
private void handleUpdateSkuStockList(Long id, PmsProductParam productParam) {
//当前的sku信息
List<PmsSkuStock> currSkuList = productParam.getSkuStockList();
//当前没有sku直接删除
if(CollUtil.isEmpty(currSkuList)){
PmsSkuStockExample skuStockExample = new PmsSkuStockExample();
skuStockExample.createCriteria().andProductIdEqualTo(id);
skuStockMapper.deleteByExample(skuStockExample);
return;
}
//获取初始sku信息
PmsSkuStockExample skuStockExample = new PmsSkuStockExample();
skuStockExample.createCriteria().andProductIdEqualTo(id);
List<PmsSkuStock> oriStuList = skuStockMapper.selectByExample(skuStockExample);
//获取新增sku信息
List<PmsSkuStock> insertSkuList = currSkuList.stream().filter(item->item.getId()==null).collect(Collectors.toList());
//获取须要更新的sku信息
List<PmsSkuStock> updateSkuList = currSkuList.stream().filter(item->item.getId()!=null).collect(Collectors.toList());
List<Long> updateSkuIds = updateSkuList.stream().map(PmsSkuStock::getId).collect(Collectors.toList());
//获取须要删除的sku信息
List<PmsSkuStock> removeSkuList = oriStuList.stream().filter(item-> !updateSkuIds.contains(item.getId())).collect(Collectors.toList());
handleSkuStockCode(insertSkuList,id);
handleSkuStockCode(updateSkuList,id);
//新增sku
if(CollUtil.isNotEmpty(insertSkuList)){
relateAndInsertList(skuStockDao, insertSkuList, id);
}
//删除sku
if(CollUtil.isNotEmpty(removeSkuList)){
List<Long> removeSkuIds = removeSkuList.stream().map(PmsSkuStock::getId).collect(Collectors.toList());
PmsSkuStockExample removeExample = new PmsSkuStockExample();
removeExample.createCriteria().andIdIn(removeSkuIds);
skuStockMapper.deleteByExample(removeExample);
}
//修改sku
if(CollUtil.isNotEmpty(updateSkuList)){
for (PmsSkuStock pmsSkuStock : updateSkuList) {
skuStockMapper.updateByPrimaryKeySelective(pmsSkuStock);
}
}
}
}
复制代码
若是咱们要在数据库中存储一些格式不固定的属性时,能够采用JSON的形式进行存储。对于关联属性的修改,能够经过一些逻辑操做来实现不改变原有ID的修改。
mall项目全套学习教程连载中,关注公众号第一时间获取。