Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十一(商品的功能实现-商品的增删改查)

1)在第一页面的时候会发起两次请求,第一次是查询商品分类,第二次是查询规格参数

在这里插入图片描述

2)修改SpecificationController当中queryParamByGid方法的参数以及方法名称

在这里插入图片描述

/*

根据参数的集合

*/

@GetMapping(“params”)

public ResponseEntity<List> queryParamList(

@RequestParam(value = “gid”,required = false) Long gid,

@RequestParam(value = “cid”,required = false) Long cid, //require当前参数设置可有可无

@RequestParam(value = “searching”,required = false) boolean searching //searching设置是否搜索

){

return ResponseEntity.ok(specificationService.queryParamList(gid,cid,searching));

}

3)完善specificationService

在这里插入图片描述

public List queryParamList(Long gid,long cid,boolean searching) {

SpecParam specParam = new SpecParam();

specParam.setGroupId(gid);

specParam.setCid(cid);

specParam.setSearching(searching);

List list = specParamMapper.select(specParam);

if(CollectionUtils.isEmpty(list)){

// 没有查询到

throw new LyException(ExceptionEnum.SPEC_PARAM_NOT_FOND);

}

return list;

}

4)运行测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

下一步

在这里插入图片描述

在这里插入图片描述

(5)实现表单提交(后台实现)
1)分析提交的参数

在这里插入图片描述

2)编写对应的实体类
a、Sku

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.pojo;

import com.sun.org.apache.xpath.internal.operations.Bool;

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_sku”)

@Data

public class Sku {

@Id

@KeySql(useGeneratedKeys = true)

private Long id;

private Long spuId;

private String title;

private String images;

private Long price;

private String ownSpec;//商品特殊规格的键值对

private String indexes;//商品特殊规格下标

private Boolean enable;//是否有效,逻辑删除用

private Date createTime; //创建时间

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

@Transient

private Integer stock;//库存

}

b、Stock

在这里插入图片描述在这里插入图片描述

package com.leyou.item.pojo;

import javax.persistence.Id;

import javax.persistence.Table;

@Table(name = “tb_stock”)

@Data

public class Stock {

@Id

private Long skuId;

private Integer seckillStock;//秒杀可以用缓存

private Integer seckillTotal;//已经秒杀数量

private Integer stock;//正常库存

}

c、完善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;

import java.util.List;

@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;

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

private List skus;

@Transient

private SpuDetail spuDetail;

}

3)创建对应的Mapper
a)SkuMapper

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.Sku;

import tk.mybatis.mapper.common.Mapper;

public interface SkuMapper extends Mapper {

}

b)SkuMapper

在这里插入图片描述

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.Stock;

import tk.mybatis.mapper.common.Mapper;

public interface StockMapper extends Mapper {

}

4)对应的Service,不需要直接使用GoodsService
5)GoodsController创建saveGoods方法

在这里插入图片描述

/*

商品的新增

*/

@PostMapping(“goods”)

public ResponseEntity saveGoods(@RequestBody Spu spu){

goodsService.saveGoods(spu);

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

}

6)完善Service层
a、设置新增商品失败的枚举

在这里插入图片描述

GOODS_SAVE_ERROR(500,“新增商品失败”),

b、完善SpuDetail的get和set方法

在这里插入图片描述

package com.leyou.item.pojo;

import lombok.Data;

import javax.persistence.Id;

import javax.persistence.Table;

@Data

@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 ; //售后服务

}

c、扩展 StockMapper
  • 在common当中定义一个通用的Mapper

    • 先引入依赖

在这里插入图片描述

    • 定义通用Mapper

在这里插入图片描述

在这里插入图片描述

package com.leyou.common.mapper;

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

import tk.mybatis.mapper.additional.insert.InsertListMapper;

import tk.mybatis.mapper.annotation.RegisterMapper;

import tk.mybatis.mapper.common.Mapper;

@RegisterMapper

public interface BaseMapper extends Mapper, IdListMapper<T,Long>, InsertListMapper {

}

    • 完善StockMapper当中继承自定义的BaseMapper(注意包路径)

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.common.mapper.BaseMapper;

import com.leyou.item.pojo.Stock;

public interface StockMapper extends BaseMapper {

}

d、完善GoodsService

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

@Transient

public void saveGoods(Spu spu) {

//新增SPU

spu.setId(null);

spu.setCreateTime(new Date());

spu.setLastUpdateTime(spu.getCreateTime());

spu.setSaleable(true);

spu.setValid(false);//设置默认不删除

int count = spuMapper.insert(spu);

if(count != 1){

throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);

}

//新增spu_detail

SpuDetail spuDetail = spu.getSpuDetail();

spuDetail.setSpuId(spu.getId());//spu新增完善会回显,然后就有spu.getId())

spuDetailMapper.insert(spuDetail);

//定义库存的集合

List stockList = new ArrayList();

//新增sku

List skus = spu.getSkus();

for (Sku sku : skus) {

sku.setCreateTime(new Date());

sku.setLastUpdateTime(sku.getCreateTime());

sku.setSpuId(spu.getId());

count = skuMapper.insert(sku);

if(count != 1){

throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);

}

//将库存放入到库存集合当中

Stock stock = new Stock();

stock.setSkuId(sku.getId());

stock.setStock(sku.getStock());

stockList.add(stock);

}

//批量新增库存

count = stockMapper.insertList(stockList);

if(count != stockList.size()){

throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);

}

}

7)运行测试

在这里插入图片描述

  • 点击保存后运行报错

在这里插入图片描述

在这里插入图片描述

  • 因为通用mapper继承的InsertListMapper接口是不支持没有自增注解的类批量添加的

  • 修改StockMapper继承additional下的InsertListMapper

在这里插入图片描述

package com.leyou.item.mapper;

import com.leyou.item.pojo.Stock;

import tk.mybatis.mapper.additional.insert.InsertListMapper;

public interface StockMapper extends InsertListMapper {

}

  • 运行测试

在这里插入图片描述

保存成功

在这里插入图片描述

二、功能补全商品参数新增


在这里插入图片描述

@PostMapping(“param”)

public ResponseEntity addSpecParam(@RequestBody SpecParam specParam){

specificationService.addSpecParam(specParam);

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

}

在这里插入图片描述

public void addSpecParam(SpecParam specParam) {

int count = specParamMapper.insert(specParam);

if(count <= 0){

throw new LyException(ExceptionEnum.BRAND_SAVE_ERROR);

}

}

三、商品的修改


0、页面分析,发起请求参数为当前商品的id

在这里插入图片描述

1、点击修改按钮商品回显(查询SPU)

(1)完善GoodsController

在这里插入图片描述

@GetMapping(“/spu/detail/{id}”)

public ResponseEntity queryDetailById(@PathVariable(“id”) Long spuId){

return ResponseEntity.ok(goodsService.queryDetailById(spuId));

}

(2)完善goodsService

在这里插入图片描述

在这里插入图片描述

public SpuDetail queryDetailById(Long spuId) {

SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(spuId);

if(spuDetail == null){

throw new LyException(ExceptionEnum.GOODS_NOT_FOND);

}

return spuDetail;

}

发送成功

在这里插入图片描述

但是第二个请求缺失败了

2、点击修改按钮商品回显(查询SKU)

1)完善GoodsController

在这里插入图片描述

/*

通过spu查询其所有sku

*/

@GetMapping(“sku/list”)

public ResponseEntity<List> querySkuBySpuId(@RequestParam(“id”) Long spuId){

return ResponseEntity.ok(goodsService.querySkuBySpuId(spuId));

}

2)完善goodsService

创建对应抛出的异常

在这里插入图片描述

GOODS_SKU_NOT_FOND(404,“商品SKU不存在”),

GOODS_STOCK_NOT_FOND(404,“商品库存存在”),

在这里插入图片描述

在这里插入图片描述

public List querySkuBySpuId(Long spuId) {

//查询SKU

Sku sku = new Sku();

sku.setSpuId(spuId);

List list = skuMapper.select(sku);

if(CollectionUtils.isEmpty(list)){

throw new LyException(ExceptionEnum.GOODS_SKU_NOT_FOND);

}

//查询库存方式一

for (Sku s : list) {

Stock stock = stockMapper.selectByPrimaryKey(s.getId());

if(stock == null){

throw new LyException(ExceptionEnum.GOODS_STOCK_NOT_FOND);

}

s.setStock(stock.getStock());

}

return list;

}

3)运行并测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、修改数据并保存数据

(1)完善GoodsController

在这里插入图片描述

/*

商品的修改

*/

@PutMapping(“goods”)

public ResponseEntity updateGoods(@RequestBody Spu spu){

goodsService.updateGoods(spu);

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

}

(2)完善goodsService
1)创建商品更新失败的枚举

在这里插入图片描述

GOODS_UPDATE_ERROR(500,“更新商品失败”),

2)完善updateGoods方法

在这里插入图片描述

在这里插入图片描述

public void updateGoods(Spu spu) {

//删除SKU

Sku sku = new Sku();

sku.setSpuId(spu.getId());

//查询sku

List skuList = skuMapper.select(sku);

if(!CollectionUtils.isEmpty(skuList)){

//删除sku

skuMapper.delete(sku);

//skuList.stream().map(Sku::getId).collect(Collectors.toList());

//代码解析.stream()将集合转换为流,map将集合当中的的所有id取出转换为集合

// 删除stock

List ids = skuList.stream().map(Sku::getId).collect(Collectors.toList());

stockMapper.deleteByIdList(ids);

}

//修改spu

spu.setValid(null);//是否有效设置为空

spu.setSaleable(null);

spu.setLastUpdateTime(new Date());

spu.setLastUpdateTime(null);

int count = spuMapper.updateByPrimaryKeySelective(spu);

if(count != 1){

throw new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);

}

//修改detail

count = spuDetailMapper.updateByPrimaryKeySelective(spu.getSpuDetail());

if(count != 1){

throw new LyException(ExceptionEnum.GOODS_UPDATE_ERROR);

}

//新增sku和stock

}

3)封装新增sku和stock的方法

将当前内容进行封装

在这里插入图片描述

在这里插入图片描述

public void saveSkuAndStock(Spu spu){

int count;

//定义库存的集合

List stockList = new ArrayList();

//新增sku

List skus = spu.getSkus();

for (Sku sku : skus) {

sku.setCreateTime(new Date());

sku.setLastUpdateTime(sku.getCreateTime());

sku.setSpuId(spu.getId());

count = skuMapper.insert(sku);

if(count != 1){

throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);

}

//将库存放入到库存集合当中

Stock stock = new Stock();

stock.setSkuId(sku.getId());

stock.setStock(sku.getStock());

stockList.add(stock);

}

//批量新增库存

count = stockMapper.insertList(stockList);

if(count != stockList.size()){

throw new LyException(ExceptionEnum.GOODS_SAVE_ERROR);

}

}

在这里插入图片描述

全部代码

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.SkuMapper;

import com.leyou.item.mapper.SpuDetailMapper;

import com.leyou.item.mapper.SpuMapper;

import com.leyou.item.mapper.StockMapper;

import com.leyou.item.pojo.*;

import org.apache.commons.lang3.StringUtils;

import org.aspectj.weaver.ast.Var;

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

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import org.springframework.util.CollectionUtils;

import tk.mybatis.mapper.entity.Example;

import java.beans.Transient;

import java.util.*;

import java.util.stream.Collectors;

import java.util.stream.Stream;

@Service

public class GoodsService {

@Autowired

private SpuMapper spuMapper;

@Autowired

private SpuDetailMapper spuDetailMapper;

@Autowired

private CategoryService categoryService;

@Autowired

private SkuMapper skuMapper;

@Autowired

private BrandService brandService;

@Autowired

private StockMapper stockMapper;

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) {

//处理父类名称

//Arrays.asList直接将参数序列化为集合

List categorylist = categoryService.queryByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

//将categorylist变为字符串平均

//提取List对象的某getName列值及排重

Stream stringStream = categorylist.stream().map(Category::getName);

//对返回的字符串集合转换为String类型的name集合

List namelist = stringStream.collect(Collectors.toList());

//将集合以/为间隔拼接为字符串

spu.setCname(StringUtils.join(namelist,“/”));

//处理品牌名称

spu.setBname(brandService.queryById(spu.getBrandId()).getName());

}

}

@Transient

public void saveGoods(Spu spu) {

//新增SPU

spu.setId(null);

最后

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

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

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

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

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

//解析分页的结果

PageInfo info = new PageInfo<>(spus);

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

}

private void loadCategoryAndBrandName(List spus) {

for (Spu spu : spus) {

//处理父类名称

//Arrays.asList直接将参数序列化为集合

List categorylist = categoryService.queryByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

//将categorylist变为字符串平均

//提取List对象的某getName列值及排重

Stream stringStream = categorylist.stream().map(Category::getName);

//对返回的字符串集合转换为String类型的name集合

List namelist = stringStream.collect(Collectors.toList());

//将集合以/为间隔拼接为字符串

spu.setCname(StringUtils.join(namelist,“/”));

//处理品牌名称

spu.setBname(brandService.queryById(spu.getBrandId()).getName());

}

}

@Transient

public void saveGoods(Spu spu) {

//新增SPU

spu.setId(null);

最后

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

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

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

[外链图片转存中…(img-DVEAgL1U-1714921876654)]

[外链图片转存中…(img-iA68kXWu-1714921876654)]

[外链图片转存中…(img-1xhf0dg2-1714921876654)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值