2-2 SPU和SKU详解及MyBatisPlus自动生成(1)

import lombok.NoArgsConstructor;

import java.io.Serializable;

/*****

  • @Author: 波波

  • @Description: 云商城

****/

@Data

@AllArgsConstructor

@NoArgsConstructor

//MyBatisPlus表映射注解

@TableName(value = “category”)

public class Category implements Serializable {

@TableId(type = IdType.AUTO)

private Integer id;

private String name;

private Integer sort;

private Integer parentId;

}

package com.bobo.vip.mall.goods.model;

import com.baomidou.mybatisplus.annotation.TableField;

import com.baomidou.mybatisplus.annotation.TableName;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;

/*****

  • @Author: 波波

  • @Description: 云商城

****/

@Data

@AllArgsConstructor

@NoArgsConstructor

//MyBatisPlus表映射注解

@TableName(value = “category_attr”)

public class CategoryAttr {

@TableField

private Integer categoryId;

@TableField

private Integer attrId;

}

/*****

  • @Author: 波波

  • @Description: 云商城

****/

@Data

@AllArgsConstructor

@NoArgsConstructor

//MyBatisPlus表映射注解

@TableName(value = “category_brand”)

public class CategoryBrand {

@TableField

private Integer categoryId;

@TableField

private Integer brandId;

}

/*****

  • @Author: 波波

  • @Description: 云商城

****/

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Product {

// Spu

private Spu spu;

// Sku

private List skus;

}

@Data

@AllArgsConstructor

@NoArgsConstructor

//MyBatisPlus表映射注解

@TableName(value = “sku”)

public class Sku {

@TableId(type = IdType.ASSIGN_ID)

private String id;

private String name;

private Integer price;

private Integer num;

private String image;

private String images;

private Date createTime;

private Date updateTime;

private String spuId;

private Integer categoryId;

private String categoryName;

private Integer brandId;

private String brandName;

private String skuAttribute;

private Integer status;

}

/*****

  • @Author: 波波

  • @Description: 云商城

****/

@Data

@AllArgsConstructor

@NoArgsConstructor

//MyBatisPlus表映射注解

@TableName(value = “sku_attribute”)

public class SkuAttribute implements Serializable {

@TableId(type = IdType.AUTO)

private Integer id;

private String name;

private String options;

private Integer sort;

//对应分类

@TableField(exist = false)

private List categories;

}

@Data

@AllArgsConstructor

@NoArgsConstructor

//MyBatisPlus表映射注解

@TableName(value = “spu”)

public class Spu {

@TableId(type = IdType.ASSIGN_ID)

private String id;

private String name;

private String intro;

private Integer brandId;

private Integer categoryOneId;

private Integer categoryTwoId;

private Integer categoryThreeId;

private String images;

private String afterSalesService;

private String content;

private String attributeList;

private Integer isMarketable;

private Integer isDelete;

private Integer status;

}

3.1 分类加载

分类功能需要实现按照父ID查询,最开始初始化加载的是顶级父类,parent_id=0,后面每次点击的时候都根据传入的id查询子分类。

1)Mapper

创建com.bobo.vip.mall.goods.mapper.CategoryMapper,代码如下:

public interface CategoryMapper extends BaseMapper {

}

2)Service

接口:com.bobo.vip.mall.goods.service.CategoryService代码如下:

public interface CategoryService extends IService {

/**

  • 根据父ID查询子分类

  • @param pid

  • @return

*/

List queryByParentId(Integer pid);

}

实现类:com.bobo.vip.mall.goods.service.impl.CategoryServiceImpl代码如下:

@Service

public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements CategoryService {

@Autowired

private CategoryMapper categoryMapper;

/***

  • 根据父ID查询子分类

  • @param pid

  • @return

*/

@Override

public List queryByParentId(Integer pid) {

//条件封装

QueryWrapper queryWrapper = new QueryWrapper();

queryWrapper.eq(“parent_id”,pid);

return categoryMapper.selectList(queryWrapper);

}

}

3)Controller

创建com.bobo.vip.mall.goods.controller.CategoryController代码如下;

@RestController

@RequestMapping(value = “/category”)

@CrossOrigin

public class CategoryController {

@Autowired

private CategoryService categoryService;

/****

  • 根据父ID查询子分类

*/

@GetMapping(value = “/parent/{pid}”)

public RespResult<List> list(@PathVariable(value = “pid”)Integer pid){

List categories = categoryService.queryByParentId(pid);

return RespResult.ok(categories);

}

}

3.2 品牌加载

品牌需要根据分类进行加载,当用户选择第3级分类的时候,加载品牌,品牌数据需要经过category_brand表关联查询。

我们可以按照如下步骤实现:

1、查询category_brand中指定分类对应的品牌ID集合

2、从brand查出品牌集合

1)Mapper

修改com.bobo.vip.mall.goods.mapper.BrandMapper,添加根据分类ID查询品牌ID集合:

//根据分类ID查询品牌集合

@Select(“select brand_id from category_brand where category_id=#{id}”)

List queryBrandIds(Integer id);

2)Service

接口:com.bobo.vip.mall.goods.service.BrandService中添加根据分类ID查询品牌集合方法

//根据分类ID查询品牌

List queryByCategoryId(Integer id);

实现类:com.bobo.vip.mall.goods.service.impl.BrandServiceImpl

/***

  • 根据分类ID查询品牌

  • @param id

  • @return

*/

@Override

public List queryByCategoryId(Integer id) {

//查询分类ID对应的品牌集合

List brandIds = brandMapper.queryBrandIds(id);

//根据品牌ID集合查询品牌信息

List brands = brandMapper.selectBatchIds(brandIds);

return brands;

}

3)Controller

修改com.bobo.vip.mall.goods.controller.BrandController添加根据分类ID查询品牌集合

/****

  • 根据分类ID查询品牌

*/

@GetMapping(value = “/category/{id}”)

public RespResult<List> categoryBrands(@PathVariable(value = “id”)Integer id){

List brands = brandService.queryByCategoryId(id);

return RespResult.ok(brands);

}

在这里插入图片描述

3.3 属性加载

属性也称为规格,属性也需要根据分类查询,我们可以按照如下思路实现:

1、先从category_attr根据分类ID查询出当前分类拥有的属性ID集合

2、从sku_attribute中查询属性集合

1)Mapper

创建com.bobo.vip.mall.goods.mapper.SkuAttributeMapper实现根据分类ID查询属性信息。

/***

  • 根据分类ID查询属性集合

  • @param id

  • @return

*/

@Select(“SELECT * FROM sku_attribute WHERE id IN(SELECT attr_id FROM category_attr WHERE category_id=#{id})”)

List queryByCategoryId(Integer id);

2)Service

接口:com.bobo.vip.mall.goods.service.SkuAttributeService添加根据分类ID查询属性集合方法

//根据分类ID查询属性集合

List queryList(Integer id);

实现类:com.bobo.vip.mall.goods.service.impl.SkuAttributeServiceImpl添加如下实现方法

/***

  • 根据分类ID查询属性集合

  • @param id

  • @return

*/

@Override

public List queryList(Integer id) {

return skuAttributeMapper.queryByCategoryId(id);

}

3)Controller

创建com.bobo.vip.mall.goods.controller.SkuAttributeController,添加如下方法

/***

  • 根据分类ID查询

*/

@GetMapping(value = “/category/{id}”)

public RespResult categoryAttributeList(@PathVariable(value = “id”)Integer id){

//根据分类ID查询属性参数

List skuAttributes = skuAttributeService.queryList(id);

return RespResult.ok(skuAttributes);

}

4、商品发布


4.1 复合对象分析

在这里插入图片描述

商品发布,如上图,我们可以发现发布的商品信息包含Sku和Spu,因此我们应该在后端能有一个对象同时能接到Spu和多个Sku,方法有很多种,我们可以直接在Spu中写一个List<Sku>,但这种方法不推荐,按照对象设计原则,对一个对象进行扩展时,尽量避免对原始对象造成改变,因此我们可以使用复合类,可以创建一个Prodcut类,该类中有Spu也有List<Sku>,代码如下:

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Product {

// Spu

private Spu spu;

// Sku

private List skus;

}

4.2 添加商品

添加商品的时候,我们需要保存Spu,同时需要添加多个Sku。我们可以在华为商城中看看真实电商中Sku名字特征,每次点击不同属性的时候,前部分名字一样,只是将名字中的规格替换了,也就是说Sku的名字其实是组合成的,一部分是Spu的一部分是Sku的,可以进行组合。

在这里插入图片描述

1)名字分析

添加商品的时候,会将商品的属性传入后台,格式如下,如果把规格名字添加到名字中,那就是华为商城中的效果了,我们可以这么做,把属性解析成Map,然后每个属性值添加到商品名字中即可。

{"适合人群":"有一定java基础的人","书籍分类":"软件编程"}

2)实现代码

Mapper

com.bobo.vip.mall.goods.mapper.SpuMapper代码如下:

public interface SpuMapper extends BaseMapper {

}

com.bobo.vip.mall.goods.mapper.SkuMapper代码如下:

public interface SkuMapper extends BaseMapper {

}

Service

com.bobo.vip.mall.goods.service.SpuService中添加产品方法如下

public interface SpuService extends IService {

//保存商品

void saveProduct(Product product);

}

com.bobo.vip.mall.goods.service.impl.SpuServiceImpl中添加产品方法如下:

@Service

public class SpuServiceImpl extends ServiceImpl<SpuMapper,Spu> implements SpuService {

@Autowired

private SkuMapper skuMapper;

@Autowired

private SpuMapper spuMapper;

@Autowired

private CategoryMapper categoryMapper;

@Autowired

private BrandMapper brandMapper;

// 保存商品

@Override

public void saveProduct(Product product) {

//Spu

Spu spu = product.getSpu();

//上架

spu.setIsMarketable(1);

//未删除

spu.setIsDelete(0);

//状态

spu.setStatus(1);

//添加

spuMapper.insert(spu);

//查询三级分类

Category category = categoryMapper.selectById(spu.getCategoryThreeId());

//查询品牌

Brand brand = brandMapper.selectById(spu.getBrandId());

//当前时间

Date now = new Date();

//新增Sku集合

for (Sku sku : product.getSkus()) {

//设置名字

String skuName = spu.getName();

Map<String,String> attrMap = JSON.parseObject(sku.getSkuAttribute(), Map.class);

for (Map.Entry<String, String> entry : attrMap.entrySet()) {

skuName+= " "+entry.getValue();

}

sku.setName(skuName);

//设置图片

sku.setImages(spu.getImages());

//设置状态

sku.setStatus(1);

//设置类目ID

sku.setCategoryId(spu.getCategoryThreeId());

//设置类目名称

sku.setCategoryName(category.getName());

//设置品牌ID

sku.setBrandId(brand.getId());

//设置品牌名称

sku.setBrandName(brand.getName());

//设置Spuid

sku.setSpuId(spu.getId());

//时间

sku.setCreateTime(now);

sku.setUpdateTime(now);

//增加

skuMapper.insert(sku);

}

}

}

Controller

创建com.bobo.vip.mall.goods.controller.SpuController,添加产品代码如下:

@Autowired

private SpuService spuService;

/***

  • 保存

*/

@PostMapping(value = “/save”)

public RespResult save(@RequestBody Product product){

//保存

spuService.saveProduct(product);

return RespResult.ok();

}

4.3 产品修改

产品修改其实和产品添加几乎一致,只需要做小改动即可,实现步骤如下:

1、如果Spu的id值不为空,说明是修改操作

2、如果是修改操作,先删除之前对应的Sku集合

3、其他流程和添加商品一致

修改com.bobo.vip.mall.goods.service.impl.SpuServiceImplsave方法,代码如下:

在这里插入图片描述

源码如下:

@Override

public void saveProduct(Product product) {

//Spu

Spu spu = product.getSpu();

//如果ID为空,则增加

if(StringUtils.isEmpty(spu.getId())){

//上架

spu.setIsMarketable(1);

//未删除

spu.setIsDelete(0);

//状态

spu.setStatus(1);

//添加

spuMapper.insert(spu);

}else{

//ID 不为空,则修改

spuMapper.updateById(spu);

//删除之前的Sku记录

skuMapper.delete(new QueryWrapper().eq(“spu_id”,spu.getId()));

}

//查询三级分类

Category category = categoryMapper.selectById(spu.getCategoryThreeId());

//查询品牌

Brand brand = brandMapper.selectById(spu.getBrandId());

//当前时间

Date now = new Date();

//新增Sku集合

for (Sku sku : product.getSkus()) {

//设置名字

String skuName = spu.getName();

Map<String,String> attrMap = JSON.parseObject(sku.getSkuAttribute(), Map.class);

for (Map.Entry<String, String> entry : attrMap.entrySet()) {

skuName+= " "+entry.getValue();

}

sku.setName(skuName);

//设置图片

sku.setImages(spu.getImages());

//设置状态

sku.setStatus(1);

//设置类目ID

sku.setCategoryId(spu.getCategoryThreeId());

//设置类目名称

sku.setCategoryName(category.getName());

//设置品牌ID

sku.setBrandId(brand.getId());

//设置品牌名称

sku.setBrandName(brand.getName());

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

面试资料整理汇总

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
Images(spu.getImages());

//设置状态

sku.setStatus(1);

//设置类目ID

sku.setCategoryId(spu.getCategoryThreeId());

//设置类目名称

sku.setCategoryName(category.getName());

//设置品牌ID

sku.setBrandId(brand.getId());

//设置品牌名称

sku.setBrandName(brand.getName());

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-aeG3oENl-1713790112529)]

[外链图片转存中…(img-BUY1YFVa-1713790112529)]

[外链图片转存中…(img-NXBmeQsa-1713790112530)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

[外链图片转存中…(img-fNmu57Qm-1713790112530)]

面试资料整理汇总

[外链图片转存中…(img-O0maNY2h-1713790112531)]

[外链图片转存中…(img-kG48zT3h-1713790112531)]

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值