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

本文详细描述了如何在SpringBoot项目中完善Service层,包括创建和处理异常枚举,以及对商品规格组(SpecGroup)和参数(SpecParam)的CRUD操作。涉及数据库设计,如SPU(标准产品单元)和SKU(库存量单位)的关系,以及它们在后端代码中的映射和操作。
摘要由CSDN通过智能技术生成
(5)完善Service层
1)创建对应抛出异常的枚举

在这里插入图片描述

SPEC_GROUP_NOT_FOND(404,“商品规格组不存在”),

2)继续完善Service

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.service;

import com.leyou.common.enums.ExceptionEnum;

import com.leyou.common.exception.LyException;

import com.leyou.item.mapper.SpecGroupMapper;

import com.leyou.item.pojo.SpecGroup;

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

import org.springframework.stereotype.Service;

import org.springframework.util.CollectionUtils;

import java.util.List;

@Service

public class SpecificationService {

@Autowired

private SpecGroupMapper specGroupMapper;

public List queryGroupByCid(Long cid) {

//设置查询条件

SpecGroup specGroup = new SpecGroup();

specGroup.setCid(cid);

List list = specGroupMapper.select(specGroup);

if(CollectionUtils.isEmpty(list)){

// 没有查询到

throw new LyException(ExceptionEnum.SPEC_GROUP_NOT_FOND);

}

return list;

}

}

(6)运行测试

在这里插入图片描述

在这里插入图片描述

3、后台代码实现规格组的添加

在这里插入图片描述

@PostMapping(“group”)

public ResponseEntity addGroup(@RequestBody SpecGroup group) {

System.out.println(group);

boolean flag = specificationService.addGroup(group);

if (!flag) {

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

}

return ResponseEntity.status(HttpStatus.CREATED).build();

}

在这里插入图片描述

public boolean addGroup(SpecGroup specGroup) {

int count = specGroupMapper.insert(specGroup);

if(count > 0){

return true;

}

return false;

}

运行测试

在这里插入图片描述

在这里插入图片描述

4、完善实现规格组的修改

在这里插入图片描述

@PutMapping(“group”)

public ResponseEntity updateGroup(@RequestBody SpecGroup group) {

System.out.println(group);

boolean flag = specificationService.updateGroup(group);

if (!flag) {

return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();

}

return ResponseEntity.status(HttpStatus.CREATED).build();

}

在这里插入图片描述

public boolean updateGroup(SpecGroup group) {

int count = specGroupMapper.updateByPrimaryKeySelective(group);

if(count > 0){

return true;

}

return false;

}

运行测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5、完善实现规格组的删除

在这里插入图片描述

@DeleteMapping(“group/{id}”)

public ResponseEntity deleteGroup(@PathVariable(“id”)Long id) {

specificationService.deleteGroupById(id);

return ResponseEntity.status(HttpStatus.CREATED).build();

}

在这里插入图片描述

public void deleteGroupById(Long id) {

SpecGroup specGroup = new SpecGroup();

specGroup.setId(id);

int count = specGroupMapper.delete(specGroup);

if(count <= 0){

// 没有查询到

throw new LyException(ExceptionEnum.INVALID_FILE_TYPE);

}

}

运行测试

在这里插入图片描述

在这里插入图片描述

删除成功

在这里插入图片描述

三、商品规格参数管理


1、页面分析

点击上面的规格组我们会发现

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们可以看到当前请求参数是规格组id,返回值为当前组下面的所有规格参数

2、实现规格参数的查询(后台实现)

1)实体类

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.pojo;

import lombok.Data;

import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Column;

import javax.persistence.Id;

import javax.persistence.Table;

@Table(name = “tb_spec_param”)

@Data

public class SpecParam {

@Id

@KeySql(useGeneratedKeys = true)

private Long id;

private Long cid;

private Long groupId;

private String name;

@Column(name = “numeric”)

private Boolean numeric;

private String unit;

private Boolean generic;

private Boolean searching;

private String segments;

}

2)实体类对应的通用Mapper

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.SpecParam;

import tk.mybatis.mapper.common.Mapper;

public interface SpecParamMapper extends Mapper {

}

3)实体类对应的Service,在SpecificationService当中注入SpecParamMapper 即可

在这里插入图片描述

@Autowired

private SpecParamMapper specParamMapper;

4)在SpecificationController当中

在这里插入图片描述

/*

根据组id查询参数

*/

@GetMapping(“params”)

public ResponseEntity<List> queryParamByGid(@RequestParam(“gid”) Long gid){

return ResponseEntity.ok(specificationService.queryParamByGid(gid));

}

5)完善SpecificationService

创建抛出异常的枚举

在这里插入图片描述

SPEC_PARAM_NOT_FOND(404,“商品规格参数不存在”),

完善SpecificationService

在这里插入图片描述

在这里插入图片描述

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 {

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

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img
img
img
img

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

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
img

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.Spu;

import tk.mybatis.mapper.common.Mapper;

public interface SpuMapper extends Mapper {

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

深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-zLaNXD34-1710881376541)]
[外链图片转存中…(img-cWOPIg6u-1710881376541)]
[外链图片转存中…(img-2MKLCTNH-1710881376542)]
[外链图片转存中…(img-BqTYZqUe-1710881376542)]

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

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-0d18wWbk-1710881376542)]

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值