Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(1)

public List queryParamByGid(Long gid) {

SpecParam specParam = new SpecParam();

specParam.setGroupId(gid);

List list = specParamMapper.select(specParam);

if(CollectionUtils.isEmpty(list)){

// 没有查询到

throw new LyException(ExceptionEnum.SPEC_PARAM_NOT_FOND);

}

return list;

}

6)重新运行并测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、SPU和SKU数据结构

(1)什么是SPU和SKU

SPU: Standard Product Unit(标准产品单位),一组具有共同属性的商品集

SKU: Stock Keeping Unit(库存量单位),SPU商品集因具体特性不同而细分的每个商品

以图为例来看:

在这里插入图片描述

  • 本页的华为就是一个商品集(SPU)

  • 因为颜色、内存等不同,而细分出不同的手机,如亮黑色128G版。(SKU)可以看出;

  • SPU是一个抽象的商品集概念,为了方便后台的管理。

  • SKU才是具体要销售的商品,每一个SKU的价格、库存可能会不一样,用户购买的是SKU而不是SPU

(2)数据库设计分析
1)思考分析

弄清楚了SPU和SKU的概念区分,接下来我们一起思考一下该如何设计数据库表。

首先来看SPU,大家一起思考下SPU应该有哪些字段来描述?

  • SPU共享数据

id:主键

title:标题

description:描述

specification:规格

packaging_list:包装

after _service:售后服务

comment:评价

category_id:商品分类

brand_id:品牌

似乎并不复杂

  • 再看下SKU(每个商品的特殊属性)

大家觉得应该有什么字段?

id:主健

spu_id:关联的

spuprice:价格

images:图片

stock:库存颜色?

内存?

硬盘?

上述做法是错误的:SKU的特有属性也是变化的。

不同分类特有属性也不一定相同。

2)SKU的特有属性

SPU中会有一些特殊属性,用来区分不同的SKU,我们称为sKU特有属性。如华为META10的颜色、内存属性.不同种类的商品,一个手机,一个衣服,其SKU属性不相同。

同一种类的商品,比如都是衣服,SKU属性基本是一样的,都是颜色、尺码等。

这样说起来,似乎SKU的特有属性也是与分类相关的?事实上,仔细观察你会发现,

SKU的特有属性是商品规格参数的一部分∶

也就是说,我们没必要单独对SKu的特有属性进行设计,它可以看做是规格参数中的一部分。这样规格参数中性可以标记成两部分:

  • 所有sku共享的规格属性〈称为通用属性),我们记录在SPU表中。

  • 每个sku不同的规格属性(称为特有属性),我们记录在SKU表中。

回一下之前我们设计的tb _spec_param表,是不是有一个字段,名为generic,标记通用和特有属性。就是为使用。

(3)SPU表
1)表结构

SPU表:

CREATE TABLE tb_spu (

id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘spu id’,

title varchar(128) NOT NULL DEFAULT ‘’ COMMENT ‘标题’,

sub_title varchar(256) DEFAULT ‘’ COMMENT ‘子标题’,

cid1 bigint(20) NOT NULL COMMENT ‘1级类目id’,

cid2 bigint(20) NOT NULL COMMENT ‘2级类目id’,

cid3 bigint(20) NOT NULL COMMENT ‘3级类目id’,

brand_id bigint(20) NOT NULL COMMENT ‘商品所属品牌id’,

saleable tinyint(1) NOT NULL DEFAULT ‘1’ COMMENT ‘是否上架,0下架,1上架’,

valid tinyint(1) NOT NULL DEFAULT ‘1’ COMMENT ‘是否有效,0已删除,1有效’,

create_time datetime DEFAULT NULL COMMENT ‘添加时间’,

last_update_time datetime DEFAULT NULL COMMENT ‘最后修改时间’,

PRIMARY KEY (id) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=195 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT=‘spu表,该表描述的是一个抽象性的商品,比如 iphone8’;

与我们前面分析的基本类似,但是似乎少了一些字段,比如商品描述。

我们做了表的垂直拆分,将SPu的详情放到了另一张表: tb_spu_detail

CREATE TABLE tb_spu_detail (

spu_id bigint(20) NOT NULL,

description text COMMENT ‘商品描述信息’,

generic_spec varchar(2048) NOT NULL DEFAULT ‘’ COMMENT ‘通用规格参数数据’,

special_spec varchar(1024) NOT NULL COMMENT ‘特有规格参数及可选值信息,json格式’,

packing_list varchar(1024) DEFAULT ‘’ COMMENT ‘包装清单’,

after_service varchar(1024) DEFAULT ‘’ COMMENT ‘售后服务’,

PRIMARY KEY (spu_id) USING BTREE

) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

在这里插入图片描述

下面的参数字段是JSON格式的字符串,与规格参数表当中的数据是一致的

在这里插入图片描述

在这里插入图片描述

(4)SKU表
1)表结构

CREATE TABLE tb_sku (

id bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘sku id’,

spu_id bigint(20) NOT NULL COMMENT ‘spu id’,

title varchar(256) NOT NULL COMMENT ‘商品标题’,

images varchar(1024) DEFAULT ‘’ COMMENT ‘商品的图片,多个图片以‘,’分割’,

price bigint(15) NOT NULL DEFAULT ‘0’ COMMENT ‘销售价格,单位为分’,

indexes varchar(32) DEFAULT ‘’ COMMENT ‘特有规格属性在spu属性模板中的对应下标组合’,

own_spec varchar(1024) DEFAULT ‘’ COMMENT ‘sku的特有规格参数键值对,json格式,反序列化时请使用linkedHashMap,保证有序’,

enable tinyint(1) NOT NULL DEFAULT ‘1’ COMMENT ‘是否有效,0无效,1有效’,

create_time datetime NOT NULL COMMENT ‘添加时间’,

last_update_time datetime NOT NULL COMMENT ‘最后修改时间’,

PRIMARY KEY (id) USING BTREE,

KEY key_spu_id (spu_id) USING BTREE

) ENGINE=InnoDB AUTO_INCREMENT=27359021729 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT=‘sku表,该表表示具体的商品实体,如黑色的 64g的iphone 8’;

还有一张表代表库存

CREATE TABLE tb_stock (

sku_id bigint(20) NOT NULL COMMENT ‘库存对应的商品sku id’,

seckill_stock int(9) DEFAULT ‘0’ COMMENT ‘可秒杀库存’,

seckill_total int(9) DEFAULT ‘0’ COMMENT ‘秒杀总数量’,

stock int(9) NOT NULL COMMENT ‘库存数量’,

PRIMARY KEY (sku_id) USING BTREE

) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT=‘库存表,代表库存,秒杀库存等信息’;

问题:为什么要将库存独立—张表?

因为库存字段写频率较高,而SKu的其它字段以读为主,因此我们将两张表分离,读写不会干扰。

特别需要注意的是sku表中的 indexes 字段和 own_spec字段。

sku中应该保存特有规格参数的值,就在这两个字段中。

在这里插入图片描述

4、功能实现

(1)页面分析

请求方式为GET

请求参数:

上架saleable是true

下降saleable是false

全部是没有saleable

key搜索的关键字

初始也page

以及显示的行数rows

在这里插入图片描述

在这里插入图片描述

发起的请求

在这里插入图片描述

(2)后台代码实现
1)实体类
a)SPU

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.pojo;

import lombok.Data;

import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;

import javax.persistence.Table;

import java.util.Date;

@Table(name = “tb_spu”)

@Data

public class Spu {

@Id

@KeySql(useGeneratedKeys = true)

private Long id;

private Long brandId;

private Long cid1; //1级类目

private Long cid2; //2级类目

private Long cid3; //2级类目

private String title;//标题

private String subTitle;//子标题

private Boolean saleable;//是否上架

private Boolean valid;//是否有效。逻辑删除用

private Date createTime;//创建时间

private Date lastUpdateTime;//最后修改时间

}

b)SPU详情SpuDetail

在这里插入图片描述

package com.leyou.item.pojo;

import lombok.Data;

import javax.persistence.Id;

import javax.persistence.Table;

@Table(name = “tb_spu_detail”)

public class SpuDetail {

@Id

private Long spuId;//对应SPU的id

private String description ; //商品描述

private String specialSpec ; //商品特殊规格的名称及可选值模板

private String genericSpec; //商品的全局规格属性

private String packingList; //包装清单

private String afterService ; //售后服务

}

2)实体类对应的mapper
a)SpuMapper

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.Spu;

import tk.mybatis.mapper.common.Mapper;

public interface SpuMapper extends Mapper {

}

b)SpuDetailMapper

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.SpuDetail;

import tk.mybatis.mapper.common.Mapper;

public interface SpuDetailMapper extends Mapper {

}

3)实体类对应的service

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.service;

import com.leyou.item.mapper.SpuDetailMapper;

import com.leyou.item.mapper.SpuMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

@Service

public class GoodsService {

@Autowired

private SpuMapper spuMapper;

@Autowired

private SpuDetailMapper spuDetailMapper;

}

4)实体类对应的Controller

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.web;

import com.leyou.item.pojo.Spu;

import com.leyou.item.service.GoodsService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping(“spu”)

public class GoodsController {

@Autowired

private GoodsService goodsService;

}

5)完善实体类对应返回的字段
a、添加依赖

在这里插入图片描述

com.fasterxml.jackson.core

jackson-databind

b、完善Spu实体类

在这里插入图片描述

package com.leyou.item.pojo;

import com.fasterxml.jackson.annotation.JsonIgnore;

import lombok.Data;

import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;

import javax.persistence.Table;

import javax.persistence.Transient;

import java.util.Date;

@Table(name = “tb_spu”)

@Data

public class Spu {

@Id

@KeySql(useGeneratedKeys = true)

private Long id;

private Long brandId;

private Long cid1; //1级类目

private Long cid2; //2级类目

private Long cid3; //2级类目

private String title;//标题

private String subTitle;//子标题

private Boolean saleable;//是否上架

@JsonIgnore //设置返回页面数据的时候,忽略当前字段

private Boolean valid;//是否有效。逻辑删除用

private Date createTime;//创建时间

@JsonIgnore //设置返回页面数据的时候,忽略当前字段

private Date lastUpdateTime;//最后修改时间

@Transient //Transient声明当前字段不是数据对应的字段

private String cname;

@Transient //Transient声明当前字段不是数据对应的字段

private String bname;

}

c、完善GoodsController

在这里插入图片描述

package com.leyou.item.web;

import com.leyou.common.vo.PageResult;

import com.leyou.item.pojo.Spu;

import com.leyou.item.service.GoodsService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping

public class GoodsController {

@Autowired

private GoodsService goodsService;

/*

分页查询SPU

*/

@GetMapping(“/spu/page”)

public ResponseEntity<PageResult> querySpuByPage(

@RequestParam(value = “page”,defaultValue = “1”) Integer page,

@RequestParam(value = “rows”,defaultValue = “5”) Integer rows,

@RequestParam(value = “saleable”,required = false) Boolean saleable,

@RequestParam(value = “key”,required = false) String key

){

return ResponseEntity.ok(goodsService.querySpuByPage(page,rows,saleable,key));

}

}

d、完善GoodsService
  • 设置对应商品查询不存在的枚举

在这里插入图片描述

GOODS_NOT_FOND(404,“商品不存在”),

  • 完善GoodsService

在这里插入图片描述

package com.leyou.item.service;

import com.github.pagehelper.PageHelper;

import com.github.pagehelper.PageInfo;

import com.leyou.common.enums.ExceptionEnum;

import com.leyou.common.exception.LyException;

import com.leyou.common.vo.PageResult;

import com.leyou.item.mapper.SpuDetailMapper;

import com.leyou.item.mapper.SpuMapper;

import com.leyou.item.pojo.Spu;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.util.CollectionUtils;

import tk.mybatis.mapper.entity.Example;

import java.util.List;

@Service

public class GoodsService {

@Autowired

private SpuMapper spuMapper;

@Autowired

private SpuDetailMapper spuDetailMapper;

public PageResult querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {

//分页

PageHelper.startPage(page,rows);

//过滤

Example example = new Example(Spu.class);

Example.Criteria criteria = example.createCriteria();

//搜索条件过滤

if(StringUtils.isNotBlank(key)){

criteria.andLike(“title”,“%”+key+“%”);//第一个参数的数据对应的字段,第二个为页面传入的参数的值

}

//上下架过滤

if(saleable != null){

criteria.andEqualTo(“saleable”,saleable);

}

//设置默认排序方式为商品的更新时间

example.setOrderByClause(“last_update_time DESC”);

//查询

List spus = spuMapper.selectByExample(example);

if(CollectionUtils.isEmpty(spus)){

throw new LyException(ExceptionEnum.GOODS_NOT_FOND);

}

//解析父类和品牌的名称

loadCategoryAndBrandName(spus);

//解析分页的结果

PageInfo info = new PageInfo<>(spus);

return new PageResult<>(info.getTotal(),spus);//将分页信息和结果集合放入PageResult当前返回到页面

}

private void loadCategoryAndBrandName(List spus) {

for (Spu spu : spus) {

//处理父类名称

//处理品牌名称

}

}

}

  • 完善CategoryService商品分类

在这里插入图片描述

public List queryByIds(List ids){

}

  • 需要扩展CategoryMapper,可以继承多个接口

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.Category;

import org.apache.ibatis.annotations.Select;

import tk.mybatis.mapper.additional.idlist.IdListMapper;

import tk.mybatis.mapper.common.Mapper;

import java.util.List;

public interface CategoryMapper extends Mapper, IdListMapper<Category,Long> {//Long第二个参数是主键类型

/**

  • 根据品牌id查询商品分类id 然后通过商品分类id查询对应所有的商品分类

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

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

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

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

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024c 备注前端获取(资料价值较高,非无偿)
img

最后

在面试前我花了三个月时间刷了很多大厂面试题,最近做了一个整理并分类,主要内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

  • HTML5新特性,语义化

  • 浏览器的标准模式和怪异模式

  • xhtml和html的区别

  • 使用data-的好处

  • meta标签

  • canvas

  • HTML废弃的标签

  • IE6 bug,和一些定位写法

  • css js放置位置和原因

  • 什么是渐进式渲染

  • html模板语言

  • meta viewport原理

该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-a7S3ySPz-1711560187289)]
[外链图片转存中…(img-si2M0t95-1711560187290)]
[外链图片转存中…(img-T65YGTfs-1711560187290)]
[外链图片转存中…(img-DuZ0TZI1-1711560187290)]
[外链图片转存中…(img-IPUPs2EH-1711560187291)]

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

[外链图片转存中…(img-Bj7xs4zf-1711560187291)]
[外链图片转存中…(img-BV9xiGta-1711560187291)]

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024c 备注前端获取(资料价值较高,非无偿)
[外链图片转存中…(img-4RZPuHqC-1711560187292)]

最后

在面试前我花了三个月时间刷了很多大厂面试题,最近做了一个整理并分类,主要内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

  • HTML5新特性,语义化

  • 浏览器的标准模式和怪异模式

  • xhtml和html的区别

  • 使用data-的好处

  • meta标签

  • canvas

  • HTML废弃的标签

  • IE6 bug,和一些定位写法

  • css js放置位置和原因

  • 什么是渐进式渲染

  • html模板语言

  • meta viewport原理

  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值