Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十(商品的规格类型以及参数管理)

Posted 蓝盒子bluebox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十(商品的规格类型以及参数管理)相关的知识,希望对你有一定的参考价值。

一、商品规格数据结构

商品中都有属性,不同商品,属性往往不同,这一部分数据很重要,我们一起来看看:

1、规格属性内容

(1) 我们看下京东中商品的规格属性︰

—款华为手机的属性:

(2)横表和竖表

值我们暂且不管,新增商品时,再来填写规格参数值即可,我们先思考规格参数模板(key)该如何设计。
来看下规格参数的结构:

  • 规格数据首先要分组,组内再有不同的规格参数
  • 不同分类,其分组名称不同
  • 不同分类,组内属性也不同

这样就意味着:有多少分类,就有多少分组,至少有数千数据,组内属性也是一样,数量更多。

如果按照传统设计,我们会以规格参数作为数据库字段名,如品牌、型号等都是字段,那么表的字段就会无限多。
这样的表称为横表。

一条信息,描述所有数据。

例如∶

我们不这么做,我们一条信息,只描述一条规格属性,也就是把规格参数作为字段的值,而非字段本身。这样的设计称为竖表设计。例如∶

  • 规格组:tb_spec_group
    • 一个商品分类下有多个规格组
  • 规格参数:tb_spec_param
    • 一个规格组下,有多个规格参数

如图:

(3)表结构

1)规格组

规格参数分组表:tb_spec_group

规格组有3个字段:

  • id:主键
  • cid:商品分类id,一个分类下有多个模板
  • name:该规格组的名称。
CREATE TABLE `tb_spec_group` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `cid` bigint(20) NOT NULL COMMENT '商品分类id,一个分类下有多个规格组',
  `name` varchar(32) NOT NULL COMMENT '规格组的名称',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `key_category` (`cid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='规格参数的分组表,每个商品分类下有多个规格参数组';
2)规格参数

规格参数表:tb_spec_param

CREATE TABLE `tb_spec_param` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `cid` bigint(20) NOT NULL COMMENT '商品分类id',
  `group_id` bigint(20) NOT NULL,
  `name` varchar(256) NOT NULL COMMENT '参数名',
  `numeric` tinyint(1) NOT NULL COMMENT '是否是数字类型参数,true或false',
  `unit` varchar(256) DEFAULT '' COMMENT '数字类型参数的单位,非数字类型可以为空',
  `generic` tinyint(1) NOT NULL COMMENT '是否是sku通用属性,true或false',
  `searching` tinyint(1) NOT NULL COMMENT '是否用于搜索过滤,true或false',
  `segments` varchar(1024) DEFAULT '' COMMENT '数值类型参数,如果需要搜索,则添加分段间隔值,如CPU频率间隔:0.5-1.0',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `key_group` (`group_id`) USING BTREE,
  KEY `key_category` (`cid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='规格参数组下的参数名';

二、商品规格组管理

1、页面布局

(1)整体布局



2、后台代码实现规格组的查询

(1)创建对应的实体类



package com.leyou.item.pojo;

import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;
import javax.persistence.Table;

@Table(name = "tb_spec_group")
@Data
public class SpecGroup {

    @Id
    @KeySql(useGeneratedKeys = true)
    private Long id;
    private Long cid;
    private String name;

}

(2)实体类对应的Mapper


package com.leyou.item.mapper;

import com.leyou.item.pojo.SpecGroup;
import tk.mybatis.mapper.common.Mapper;

public interface SpecGroupMapper extends Mapper<SpecGroup> {



}

(3)实体类对应的Service


package com.leyou.item.service;

import org.springframework.stereotype.Service;

@Service
public class SpecificationService {
}

(4)实体类对应的Controller(根据分类id查询规格组)


package com.leyou.item.web;

import com.leyou.item.pojo.SpecGroup;
import com.leyou.item.service.SpecificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("spec")
public class SpecificationController {
    @Autowired
    private SpecificationService specificationService;
    @GetMapping("groups/{cid}")
    public ResponseEntity<List<SpecGroup>> queryGroupByCid(@PathVariable("cid")Long cid){

        return ResponseEntity.ok(specificationService.queryGroupByCid(cid));

    }
}

(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<SpecGroup> queryGroupByCid(Long cid) {
        //设置查询条件
        SpecGroup specGroup = new SpecGroup();
        specGroup.setCid(cid);
        List<SpecGroup> list = specGroupMapper.select(specGroup);
        if(CollectionUtils.isEmpty(list)){
            // 没有查询到
            throw new LyException(ExceptionEnum.SPEC_GROUP_NOT_FOND);
        }
        return list;

    }
}

(6)运行测试


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


    @PostMapping("group")
    public ResponseEntity<Void> 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<Void> 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<Void> 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<SpecParam> {

}

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


    @Autowired
    private SpecParamMapper specParamMapper;

4)在SpecificationController当中

  /*
    根据组id查询参数
     */
    @GetMapping("params")
    public ResponseEntity<List<SpecParam>> queryParamByGid(@RequestParam("gid") Long gid){

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

5)完善SpecificationService

创建抛出异常的枚举

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

完善SpecificationService


    public List<SpecParam> queryParamByGid(Long gid) {

        SpecParam specParam = new SpecParam();
        specParam.setGroupId(gid);

        List<SpecParam> list = specParamMapper.select(specParam);
        if(CollectionUtils.isEmpty(list)){
            // 没有查询到
            以上是关于Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十(商品的规格类型以及参数管理)的主要内容,如果未能解决你的问题,请参考以下文章

IDEA SpringBoot 项目打包成jar包

JavaEE 之 SpringBoot

面试-科大讯飞日常实习面试

(超详解)SpringBoot高级部分-自动配置+监听机制+监控+项目部署

Java项目:超市进销存系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)

SpringBoot核心注解应用