2.新增和修改商品
2.1 概念与表结构分析
2.1.1 SPU与SKU概念
**SPU = Standard Product Unit (标准产品单位) **
- 概念 : SPU 是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
- 通俗点讲,属性值、特性相同的货品就可以称为一个 SPU
- 例如:华为P30 就是一个 SPU
SKU=stock keeping unit( 库存量单位**)**
- SKU 即库存进出计量的单位, 可以是以件、盒、托盘等为单位。
- SKU 是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。
- 在服装、鞋类商品中使用最多最普遍。
例如:华为P30 红色 64G 就是一个 SKU
2.1.2 表结构分析
tb_spu 表 (SPU表)
tb_sku 表(SKU商品表)
2.2 实现思路
前端传递给后端的数据格式 是一个spu对象和sku列表组成的对象
2.3 代码实现
2.3.1 SPU与SKU列表的保存
代码实现:
(1)changgou_service_goods_api工程创建组合实体类Goods
package com.changgou.goods.pojo;
import java.util.List;
public class Goods {
//spu
private Spu spu;
//sku集合
private List<Sku> skuList;
public Spu getSpu() {
return spu;
}
public void setSpu(Spu spu) {
this.spu = spu;
}
public List<Sku> getSkuList() {
return skuList;
}
public void setSkuList(List<Sku> skuList) {
this.skuList = skuList;
}
}
(2)changgou_service_goods工程SpuService新增方法add(Goods goods)
/**
* 增加
* @param goods
*/
@Transactional
@Override
public void add(Goods goods){
//1.添加spu
Spu spu = goods.getSpu();
//设置分布式id
long spuId = idWorker.nextId();
spu.setId(String.valueOf(spuId));
//设置删除状态.
spu.setIsDelete("0");
//上架状态
spu.setIsMarketable("0");
//审核状态
spu.setStatus("0");
spuMapper.insertSelective(spu);
//2.添加sku集合
this.saveSkuList(goods);
}
//添加sku数据
private void saveSkuList(Goods goods) {
Spu spu = goods.getSpu();
//查询分类对象
Category category = categoryMapper.selectByPrimaryKey(spu.getCategory3Id());
//查询品牌对象
Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
//设置品牌与分类的关联关系
//查询关联表
CategoryBrand categoryBrand = new CategoryBrand();
categoryBrand.setBrandId(spu.getBrandId());
categoryBrand.setCategoryId(spu.getCategory3Id());
int count = categoryBrandMapper.selectCount(categoryBrand);
if (count == 0){
//品牌与分类还没有关联关系
categoryBrandMapper.insert(categoryBrand);
}
//获取sku集合
List<Sku> skuList = goods.getSkuList();
if (skuList != null){
//遍历sku集合,循环填充数据并添加到数据库中
for (Sku sku : skuList) {
//设置skuId
sku.setId(String.valueOf(idWorker.nextId()));
//设置sku规格数据
if (StringUtils.isEmpty(sku.getSpec())){
sku.setSpec("{}");
}
//设置sku名称(spu名称+规格)
String name = spu.getName();
//将规格json转换为map,将map中的value进行名称的拼接
Map<String,String> specMap = JSON.parseObject(sku.getSpec(), Map.class);
if (specMap != null && specMap.size()>0){
for (String value : specMap.values()) {
name+=" "+value;
}
}
sku.setName(name);
//设置spuid
sku.setSpuId(spu.getId());
//设置创建与修改时间
sku.setCreateTime(new Date());
sku.setUpdateTime(new Date());
//商品分类id
sku.setCategoryId(category.getId());
//设置商品分类名称
sku.setCategoryName(category.getName());
//设置品牌名称
sku.setBrandName(brand.getName());
//将sku添加到数据库
skuMapper.insertSelective(sku);
}
}
}
(3)修改SpuController的add方法
/***
* 新增数据
* @param goods
* @return
*/
@PostMapping
public Result add(@RequestBody Goods goods){
spuService.add(goods);
return new Result(true,StatusCode.OK,"添加成功");
}
2.3.2 品牌与分类关联
实现思路:
将分类ID与SPU的品牌ID 一起插入到tb_category_brand表中
(1)创建实体类
package com.changgou.goods.pojo;
import javax.persistence.Id;
import javax.persistence.Table;
@Table(name = "tb_category_brand")
public class CategoryBrand {
//分类id
@Id
private Integer categoryId;
//品牌id
@Id
private Integer brandId;
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public Integer getBrandId() {
return brandId;
}
public void setBrandId(Integer brandId) {
this.brandId = brandId;
}
}
这个表是联合主键,所以templateId和brandId都有@Id注解
(2)新建数据访问接口
public interface CategoryBrandMapper extends Mapper<CategoryBrand> {
}
(3)SpuServiceImpl引入
@Autowired
private CategoryMapper categoryMapper;
修改SpuServiceImpl的saveSkuList方法,添加分类与品牌之间的关联, 修改后代码如下:
//添加sku数据
private void saveSkuList(Goods goods) {
Spu spu = goods.getSpu();
//查询分类对象
Category category = categoryMapper.selectByPrimaryKey(spu.getCategory3Id());
//查询品牌对象
Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
//设置品牌与分类的关联关系
//查询关联表
CategoryBrand categoryBrand = new CategoryBrand();
categoryBrand.setBrandId(spu.getBrandId());
categoryBrand.setCategoryId(spu.getCategory3Id());
int count = categoryBrandMapper.selectCount(categoryBrand);
if (count == 0){
//品牌与分类还没有关联关系
categoryBrandMapper.insert(categoryBrand);
}
//获取sku集合
List<Sku> skuList = goods.getSkuList();
if (skuList != null){
//遍历sku集合,循环填充数据并添加到数据库中
for (Sku sku : skuList) {
//设置skuId
sku.setId(String.valueOf(idWorker.nextId()));
//设置sku规格数据
if (StringUtils.isEmpty(sku.getSpec())){
sku.setSpec("{}");
}
//设置sku名称(spu名称+规格)
String name = spu.getName();
//将规格json转换为map,将map中的value进行名称的拼接
Map<String,String> specMap = JSON.parseObject(sku.getSpec(), Map.class);
if (specMap != null && specMap.size()>0){
for (String value : specMap.values()) {
name+=" "+value;
}
}
sku.setName(name);
//设置spuid
sku.setSpuId(spu.getId());
//设置创建与修改时间
sku.setCreateTime(new Date());
sku.setUpdateTime(new Date());
//商品分类id
sku.setCategoryId(category.getId());
//设置商品分类名称
sku.setCategoryName(category.getName());
//设置品牌名称
sku.setBrandName(brand.getName());
//将sku添加到数据库
skuMapper.insertSelective(sku);
}
}
}
2.3.3 根据ID查询商品
需求:根据id 查询SPU和SKU列表 .
代码实现:
(1)changgou_service_goods工程SpuService新增方法定义
/**
* 根据ID查询商品
* @param id
* @return
*/
public Goods findGoodsById(String id);
(2)changgou_service_goods工程SpuServiceImpl实现此方法
/**
* 根据id查询spu与sku列表信息
* @param id
* @return
*/
@Override
public Goods findGoodsById(String id) {
Goods goods = new Goods();
//查询spu,封装到goods
Spu spu = spuMapper.selectByPrimaryKey(id);
goods.setSpu(spu);
//查询sku集合,封装到goods
Example example = new Example(Sku.class);
Example.Criteria criteria = example.createCriteria();
//根据spu进行sku列表的查询
criteria.andEqualTo("spuId",id);
List<Sku> skuList = skuMapper.selectByExample(example);
goods.setSkuList(skuList);
return goods;
}
(3)修改SpuController的findById方法
/***
* 根据ID查询数据
* @param id
* @return
*/
@GetMapping("/{id}")
public Result findById(@PathVariable String id){
//Spu spu = spuService.findById(id);
Goods goods = spuService.findGoodsById(id);
return new Result(true,StatusCode.OK,"查询成功",goods);
}
2.3.4 保存修改
(1)changgou_service_goods工程SpuService新增方法定义
/
***
* 修改数据
* @param spu
*/
void update(Goods goods);
(2)changgou_service_goods工程SpuServiceImpl实现此方法
/**
* 修改
* @param goods
*/
@Transactional
@Override
public void update(Goods goods){
//修改spu
Spu spu = goods.getSpu();
spuMapper.updateByPrimaryKey(spu);
//修改sku,应该实现呢?
//删除原有的sku列表
Example example = new Example(Sku.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("spuId",spu.getId());
skuMapper.deleteByExample(example);
//现有的新的sku列表进行重新添加
this.saveSkuList(goods);
}
(3)修改SpuController的update方法
/***
* 修改数据
* @param goods
* @param id
* @return
*/
@PutMapping(value="/{id}")
public Result update(@RequestBody Goods goods,@PathVariable String id){
spuService.update(goods);
return new Result(true,StatusCode.OK,"修改成功");
}