云商城--业务+架构学习和环境准备

云商城业务+架构学习和环境准备

B2B:Business to Business,交易双方的身份都是商家,也就是商家将商品卖给商家,类似采购、批发类购物,国内代表性网站阿里巴巴批发网

C2C:Customer to Customer,交易双方都可以是个人,比如淘宝网

O2O:Online To Offline,线上线下模式,典型的代表饿了么,在线上支付了,在线下获取商品

B2B2C:大型的电商平台,允许商家入驻,允许会员在平台买卖商品,京东和天猫都属于这类型网站

1.云商城业务场景

1.1 业务学习

​ 云商城是基于SpringCloud Alibaba技术栈研发的B2C电商平台,平台拥有核心的电商业务功能。运营商在后台管理商品,前台能通过搜索引擎实时搜索到最新商品,用户注册后可以直接在平台购买商品,并通过微信支付实现线上支付。用户还能参与平台秒杀抢购,并实现线上支付秒杀商品

1.2 功能学习

1.商品管理

在这里插入图片描述

2.商城首页

在这里插入图片描述

3.海量商品实时搜索

在这里插入图片描述

4.商品及时秒杀

在这里插入图片描述

5.购物车管理

在这里插入图片描述

6.在线微信支付

在这里插入图片描述

2.商城架构设计

在这里插入图片描述

云商城采用了微服务技术架构,采用了当前主流的SpringCloud Alibaba技术栈,从接入层、网关层、服务层、数据同步、服务治理、数据处理、第三方接口多个方面进行了精心设计

具体流程:LVS四层负载,抗压能力更强(LVS一般能到达400万并发),然后lvs会把请求路由给nginx七层负载(抗压能力能达到5万)经过了nginx,然后通过网关gateway(路由、限流、鉴权),然后路由到不同的服务(取决于我们的业务),利用分布式事务解决数据不一致性问题,涉及到的数据库包括MySQL、redis、es

在这里插入图片描述

3.云商城表结构

在这里插入图片描述

3.1 商品数据库

品牌表:brand

CREATE TABLE `brand` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '品牌id',
  `name` varchar(100) NOT NULL COMMENT '品牌名称',
  `image` varchar(1000) DEFAULT '' COMMENT '品牌图片地址',
  `initial` varchar(1) DEFAULT '' COMMENT '品牌的首字母',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=325475 DEFAULT CHARSET=utf8 COMMENT='品牌表';

商品分类表:category

CREATE TABLE `category` (
  `id` int(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID',
  `name` varchar(50) DEFAULT NULL COMMENT '分类名称',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  `parent_id` int(20) DEFAULT NULL COMMENT '上级ID',#这个parent_id就是id,自己查自己,自关联表
  PRIMARY KEY (`id`),
  KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11177 DEFAULT CHARSET=utf8 COMMENT='商品类目';

品牌分类关联表:category_brand

CREATE TABLE `category_brand` (
  `category_id` int(11) NOT NULL COMMENT '分类ID',
  `brand_id` int(11) NOT NULL COMMENT '品牌ID',
  PRIMARY KEY (`brand_id`,`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

商品属性表:sku_attribute

CREATE TABLE `sku_attribute` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(50) DEFAULT NULL COMMENT '属性名称',
  `options` varchar(2000) DEFAULT NULL COMMENT '属性选项',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  `category_id` varchar(100) DEFAULT NULL COMMENT '分类ID集合',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=140 DEFAULT CHARSET=utf8;

商品SPU表:spu

CREATE TABLE `spu` (
  `id` varchar(60) NOT NULL COMMENT '主键',
  `name` varchar(100) DEFAULT NULL COMMENT 'SPU名',
  `intro` varchar(200) DEFAULT NULL COMMENT '商品简介',
  `brand_id` int(11) DEFAULT NULL COMMENT '品牌ID',
  `category_one_id` int(20) DEFAULT NULL COMMENT '一级分类',
  `category_two_id` int(10) DEFAULT NULL COMMENT '二级分类',
  `category_three_id` int(10) DEFAULT NULL COMMENT '三级分类',
  `images` varchar(1000) DEFAULT NULL COMMENT '图片列表',
  `after_sales_service` varchar(50) DEFAULT NULL COMMENT '售后服务',
  `content` longtext COMMENT '介绍',
  `attribute_list` varchar(3000) DEFAULT NULL COMMENT '规格列表',
  `is_marketable` int(1) DEFAULT '0' COMMENT '是否上架,0已下架,1已上架',
  `is_delete` int(1) DEFAULT '0' COMMENT '是否删除,0:未删除,1:已删除',
  `status` int(1) DEFAULT '0' COMMENT '审核状态,0:未审核,1:已审核,2:审核不通过',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

商品SKU表:sku

CREATE TABLE `sku` (
  `id` varchar(60) NOT NULL COMMENT '商品id',
  `name` varchar(200) NOT NULL COMMENT 'SKU名称',
  `price` int(20) NOT NULL DEFAULT '1' COMMENT '价格(分)',
  `num` int(10) DEFAULT '100' COMMENT '库存数量',
  `image` varchar(200) DEFAULT NULL COMMENT '商品图片',
  `images` varchar(2000) DEFAULT NULL COMMENT '商品图片列表',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `spu_id` varchar(60) DEFAULT NULL COMMENT 'SPUID',
  `category_id` int(10) DEFAULT NULL COMMENT '类目ID',
  `category_name` varchar(200) DEFAULT NULL COMMENT '类目名称',
  `brand_name` varchar(100) DEFAULT NULL COMMENT '品牌名称',
  `sku_attribute` varchar(200) DEFAULT NULL COMMENT '规格',
  `status` int(1) DEFAULT '1' COMMENT '商品状态 1-正常,2-下架,3-删除',
  PRIMARY KEY (`id`),
  KEY `cid` (`category_id`),
  KEY `status` (`status`),
  KEY `updated` (`update_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表';

3.2 订单数据库

订单表:order

CREATE TABLE `order` (
  `id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '订单id',
  `total_num` int(11) DEFAULT NULL COMMENT '数量合计',
  `moneys` int(11) DEFAULT NULL COMMENT '金额合计',
  `pay_type` varchar(1) COLLATE utf8_bin DEFAULT NULL COMMENT '支付类型,1、在线支付、0 货到付款',
  `create_time` datetime DEFAULT NULL COMMENT '订单创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '订单更新时间',
  `pay_time` datetime DEFAULT NULL COMMENT '付款时间',
  `consign_time` datetime DEFAULT NULL COMMENT '发货时间',
  `end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
  `username` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名称',
  `recipients` varchar(50) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人',
  `recipients_mobile` varchar(12) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人手机',
  `recipients_address` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '收货人地址',
  `weixin_transaction_id` varchar(30) COLLATE utf8_bin DEFAULT NULL COMMENT '交易流水号',
  `order_status` int(1) COLLATE utf8_bin DEFAULT NULL COMMENT '订单状态,0:未完成,1:已完成,2:已退货',
  `pay_status` int(1) COLLATE utf8_bin DEFAULT NULL COMMENT '支付状态,0:未支付,1:已支付,2:支付失败',
  `is_delete` int(1) COLLATE utf8_bin DEFAULT NULL COMMENT '是否删除',
  PRIMARY KEY (`id`),
  KEY `create_time` (`create_time`),
  KEY `status` (`order_status`),
  KEY `payment_type` (`pay_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

订单明细表:order_sku

CREATE TABLE `order_sku` (
  `id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT 'ID',
  `category_one_id` int(11) DEFAULT NULL COMMENT '1级分类',
  `category_two_id` int(11) DEFAULT NULL COMMENT '2级分类',
  `category_three_id` int(11) DEFAULT NULL COMMENT '3级分类',
  `spu_id` varchar(60) COLLATE utf8_bin DEFAULT NULL COMMENT 'SPU_ID',
  `sku_id` varchar(60) COLLATE utf8_bin DEFAULT NULL COMMENT 'SKU_ID',
  `order_id` varchar(50) COLLATE utf8_bin NOT NULL COMMENT '订单ID',
  `name` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '商品名称',
  `price` int(20) DEFAULT NULL COMMENT '单价',
  `num` int(10) DEFAULT NULL COMMENT '数量',
  `money` int(20) DEFAULT NULL COMMENT '总金额',
  `image` varchar(200) COLLATE utf8_bin DEFAULT NULL COMMENT '图片地址',
  PRIMARY KEY (`id`),
  KEY `item_id` (`sku_id`),
  KEY `order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

3.3 秒杀数据库

秒杀商品表:seckill_goods

CREATE TABLE `seckill_goods` (
  `id` varchar(60) NOT NULL,
  `sup_id` varchar(60) DEFAULT NULL COMMENT 'spu ID',
  `sku_id` varchar(60) DEFAULT NULL COMMENT 'sku ID',
  `name` varchar(100) DEFAULT NULL COMMENT '标题',
  `images` varchar(150) DEFAULT NULL COMMENT '商品图片',
  `price` int(20) DEFAULT NULL COMMENT '原价格',
  `seckill_price` double(20,0) DEFAULT NULL COMMENT '秒杀价格',
  `create_time` datetime DEFAULT NULL COMMENT '添加日期',
  `start_time` datetime DEFAULT NULL COMMENT '开始时间',
  `end_time` datetime DEFAULT NULL COMMENT '结束时间',
  `num` int(11) DEFAULT NULL COMMENT '秒杀商品数',
  `store_count` int(11) DEFAULT NULL COMMENT '剩余库存数',
  `content` varchar(2000) DEFAULT NULL COMMENT '描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

秒杀订单表:seckill_order

CREATE TABLE `seckill_order` (
  `id` varchar(60) NOT NULL COMMENT '主键',
  `seckill_goods_id` varchar(60) DEFAULT NULL COMMENT '秒杀商品ID',
  `money` int(10) DEFAULT NULL COMMENT '支付金额',
  `username` varchar(50) DEFAULT NULL COMMENT '用户',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `pay_time` datetime DEFAULT NULL COMMENT '支付时间',
  `status` int(1) DEFAULT NULL COMMENT '状态,0未支付,1已支付',
  `weixin_transaction_id` varchar(30) DEFAULT NULL COMMENT '交易流水',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3.4 用户数据库

省份表:provinces

CREATE TABLE `provinces` (
  `provinceid` varchar(20) NOT NULL COMMENT '省份ID',
  `province` varchar(50) NOT NULL COMMENT '省份名称',
  PRIMARY KEY (`provinceid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='省份信息表';

城市表:cities

CREATE TABLE `cities` (
  `cityid` varchar(20) NOT NULL COMMENT '城市ID',
  `city` varchar(50) NOT NULL COMMENT '城市名称',
  `provinceid` varchar(20) NOT NULL COMMENT '省份ID',
  PRIMARY KEY (`cityid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='行政区域地州市信息表';

区域表:areas

CREATE TABLE `areas` (
  `areaid` varchar(20) NOT NULL COMMENT '区域ID',
  `area` varchar(50) NOT NULL COMMENT '区域名称',
  `cityid` varchar(20) NOT NULL COMMENT '城市ID',
  PRIMARY KEY (`areaid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='行政区域县区信息表';

收件信息表:address

CREATE TABLE `address` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL COMMENT '用户名',
  `provinceid` varchar(20) DEFAULT NULL COMMENT '省',
  `cityid` varchar(20) DEFAULT NULL COMMENT '市',
  `areaid` varchar(20) DEFAULT NULL COMMENT '县/区',
  `phone` varchar(20) DEFAULT NULL COMMENT '电话',
  `address` varchar(200) DEFAULT NULL COMMENT '详细地址',
  `contact` varchar(50) DEFAULT NULL COMMENT '联系人',
  `is_default` int(1) DEFAULT NULL COMMENT '是否是默认 1默认 0否',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8;

4.工程搭建

4.1 环境准备

在这里插入图片描述

这里需要用到数据库MySQL和注册中心Nacos,数据库和注册中心全部已经安装在了虚拟机中.

虚拟机ip:192.168.100.130

虚拟机账号:root

账号密码:pcb

数据库账号:root

数据库密码:123456

Nacos   url   http://192.168.100.130:8848/nacos
              账号:nacos
              密码:nacos

基于Docker安装Nacos:

docker run -d -p 8848:8848 -e MODE=standalone -v /opt/nacos/init.d/custom.properties:/home/nacos/init.d/custom.properties -v /opt/nacos/logs:/home/nacos/logs --restart always --name nacos nacos/nacos-server

安装好了后,访问http://192.168.100.130:8848/nacos 账号密码都是nacos

基于Docker安装MySQL:

docker run -di --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

4.2 工程结构分析

在这里插入图片描述

4.3 公共工程搭建

4.3.1 父工程搭建(顶级)

工程坐标:

<groupId>com.gupaoedu.vip.mall</groupId>
<artifactId>gupaoedu-vip-mall</artifactId>
<version>0.0.1-SNAPSHOT</version>

我们选择用Spring Initializr创建父工程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

选择需要的应用场景

在这里插入图片描述

整理下pom.xml,在pom.xml中只留部分包,其他包是创建微服务时需要(所有模块都要用的包)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gupaoedu.vip.mall</groupId>
    <artifactId>gupaoedu-vip-mall</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gupaoedu-vip-mall</name>
    <!--父工程-->
    <packaging>pom</packaging>
    <description>云商城</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    </properties>

    <dependencies>
        <!--lombok,方便创建Bean对象和日志操作-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--Test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--热部署插件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!--alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
4.3.2 子项目父工程创建

我们可以按照功能分类,给每类工程创建一个父工程,方便管理(建maven模块)

mall-api:存储所有数据库表对应的Bean和Feign接口
mall-gateway:存储所有微服务网关
mall-service:存储所有微服务工程
mall-util:存储公共工程
mall-web:存储所有和页面渲染有关的工程

mall-api的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gupaoedu-vip-mall</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <artifactId>mall-api</artifactId>
    <description>
        存放所有JavaBean和Feign接口
    </description>
</project>

mall-gateway的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gupaoedu-vip-mall</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <artifactId>mall-gateway</artifactId>
    <description>
        存放微服网关集群
    </description>

</project>

mall-service的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gupaoedu-vip-mall</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <artifactId>mall-service</artifactId>
    <description>所有的应用服务</description>
</project>

mall-util的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gupaoedu-vip-mall</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <artifactId>mall-util</artifactId>
    <description>
        存放所有公共工程
    </description>
</project>

mall-web的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gupaoedu-vip-mall</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <artifactId>mall-web</artifactId>
    <description>
        存放所有和页面渲染有关的工程,不建议放在service中,所有service只提供基于RESTful的服务
    </description>
</project>
4.3.3 公共工程创建

在这里插入图片描述

4.3.3.1 公共依赖汇总

service中以后要创建微服务工程操作数据库,我们可以把所有service需要用到的包以及所有service需要初始化的对象放到一个独立的工程中,以后哪个工程要用,直接依赖即可。

mall-util中创建mall-service-dependency,pom.xml依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mall-util</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mall-service-dependency</artifactId>
    <description>
        所有service工程依赖的包汇总以及初始化工具包
    </description>

    <dependencies>
        <!--web包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--MyBatis Plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>

        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--Redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--Nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
</project>
4.3.3.2 公共工具包

我们需要用到的工具包也可以单独放到一个工程中,每次要用,直接依赖即可

mall-util中创建mall-common,我们在工程中创建2个对象:

用于指定响应状态码的枚举对象:com.gupaoedu.mall.util.RespCode

public enum RespCode {

    SUCCESS(200, "操作成功"),
    ERROR(500, "操作失败"),
    SYSTEM_ERROR(501, "系统错误");

    private Integer code;
    private String message;

    RespCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    RespCode() {
    }
    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

用于响应用户信息封装的对象:com.gupaoedu.mall.util.RespResult

public class RespResult<T> implements Serializable {

    //响应数据结果集
    private T data;

    /**
     * 状态码
     * 200 操作成功
     * 500 操作失败
     */
    private Integer code;

    /***
     * 响应信息
     */
    private String message;

    public RespResult() {
    }

    public RespResult(RespCode resultCode) {
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }

    public RespResult(T data, RespCode resultCode) {
        this.data = data;
        this.code = resultCode.getCode();
        this.message = resultCode.getMessage();
    }
    public static RespResult ok() {
        return new RespResult(null, RespCode.SUCCESS);
    }

    public static RespResult ok(Object data) {
        return new RespResult(data, RespCode.SUCCESS);
    }

    public static RespResult error() {
        return new RespResult(null, RespCode.ERROR);
    }

    public static RespResult error(String message) {
        return secByError(RespCode.ERROR.getCode(),message);
    }

    //自定义异常
    public static RespResult secByError(Integer code,String message) {
        RespResult err = new RespResult();
        err.setCode(code);
        err.setMessage(message);
        return err;
    }

    public static RespResult error(RespCode resultCode) {
        return new RespResult(resultCode);
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
4.3.3.3 依赖管理

service工程一定会依赖mall-service-dependencymall-common,我们可以修改mall-service将这两个工程添加到依赖中:

<dependencies>
    <!--依赖mall-service-dependency-->
    <dependency>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <artifactId>mall-service-dependency</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <!--依赖mall-common-->
    <dependency>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <artifactId>mall-common</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

5.品牌管理实现

5.1 集成MyBatisPlus

5.1.1 MyBatis Plus介绍

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

MyBatis Plus特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
5.1.2 MyBatisPlus集成

1)引入依赖包

mall-service-dependency中引入如下依赖(这个依赖包之前已经引入了,这里无需再次引入):

<!--MyBatis Plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>

mall-api中引入如下依赖(编写JavaBean会用到MyBatis Plus的相关注解,引入依赖防止程序编译不通过):

<!--MyBatis Plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
    <scope>provided</scope>
</dependency>

2)创建goods-api工程

mall-api中创建子工程goods-api,用于创建shop_goods数据库表对应的实体Bean和Feign接口

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mall-api</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>goods-api</artifactId>
    <description>
        shop_goods数据库表对应的JavaBean
    </description>
</project>

goods-api中创建com.gupaoedu.vip.mall.goods.Brand,代码如下:

javaBean与数据库表的对应

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("brand")  //MyBatisPlus表映射注解
public class Brand {

    //品牌ID
    //MyBatisPlus主键策略注解
    @TableId(type = IdType.AUTO)
    private Integer id;
    //品牌名字
    private String name;
    //品牌图片
    private String image;
    //品牌首字母
    private String initial;
    //品牌排序
    private Integer sort;
}

主键生成策略

AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID) ,已过时
UUID32位UUID字符串,已过时
ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID) ,已过时

3)商品微服务

mall-service中创建mall-goods-service微服务,用于操作shop_goods数据库

pom.xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mall-service</artifactId>
        <groupId>com.gupaoedu.vip.mall</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mall-goods-service</artifactId>
    <description>
        shop_goods微服务
    </description>

    <dependencies>
        <!--goods-api依赖,需要brand实体类-->
        <dependency>
            <groupId>com.gupaoedu.vip.mall</groupId>
            <artifactId>goods-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

创建bootstrap.yml,配置如下:

server:
  port: 8081
spring:
  application:
    name: mall-goods #服务名
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/shop_goods?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456
  cloud:
    nacos:
      config:
        file-extension: yaml
        server-addr: 192.168.1.11:8848
      discovery:
        #Nacos的注册地址
        server-addr: 192.168.1.11:8848
# ====================MybatisPlus====================
mybatis-plus:
  mapper-locations: mapper/*.xml
  type-aliases-package: com.gupaoedu.vip.mall.*.model  #javaBean取别名的位置
  configuration:
    map-underscore-to-camel-case: true  #驼峰命名法,eg:t_user
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

#日志配置
logging:
  pattern:
    console: "%msg%n"

配置说明:

type-aliases-package:指定JavaBean的别名包,和MyBatis用法一样
mapper-locations:复杂的操作可能需要自己写SQL,SQL可以写到xml文件中,这里指定和Dao对应的xml文件,此时我们需要在resources中创建一个mapper目录
map-underscore-to-camel-case:开启驼峰功能,数据库表列名如果有_,可以自动按驼峰命名规则转换
log-impl:日志开启,方便测试

创建启动类com.gupaoedu.vip.mall.MallGoodsServiceApplication

/**
 * 商品服务启动类
 */
@SpringBootApplication
@MapperScan(basePackages = {"com.gupaoedu.vip.mall.goods.mapper"})
public class MallGoodsApplication {

    public static void main(String[] args) {
        SpringApplication.run(MallGoodsApplication.class,args);
    }
}

此时启动程序,查看Nacos控制台:< http://192.168.1.11:8848/nacos/index.html> 账号和密码都是nacos,效果如下:

在这里插入图片描述

5.2 MyBatisPlus操作

我们创建一个品牌操作的功能,实现品牌增删改查,分别创建modelmapperservicecontroller

MyBatisPlus提供了很多通用方法:

mapper(接口)->extends BaseMapper【增删改查】
service(接口)->extends IService【增删改查】
serviceImpl->extends ServiceImpl【增删改查】
5.2.1 Mapper创建

mall-goods-service创建com.gupaoedu.vip.mall.goods.mapper.BrandMapper接口,代码如下:

public interface BrandMapper extends BaseMapper<Brand> {
}

代码说明:BaseMapper中已经存在了很多常见数据库操作方法,可以大幅提升开发速度

5.2.2 Service创建

mall-goods-service创建com.gupaoedu.vip.mall.goods.service.BrandService接口,代码如下:

public interface BrandService extends IService<Brand>{
}

mall-goods-service创建com.gupaoedu.vip.mall.goods.service.impl.BrandServiceImpl实现类,代码如下:

@Service
public class BrandServiceImpl extends ServiceImpl<BrandMapper,Brand> implements BrandService {}

代码说明:IServiceServiceImpl中已经创建好了很多常用的增删改查方法,我们写常用的增删改查,几乎不用写方法

5.2.3 增删改功能

增删改功能在IServiceServiceImpl中已经全部存在, 不需要额外添加方法,只需要在Controller调用即可

mall-goods-service创建com.gupaoedu.vip.mall.goods.controller.BrandController,代码如下:

注意:@PathVariable 映射 URL 绑定的占位符,通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中

@RestController
@RequestMapping(value = "/brand")
public class BrandController {

    @Autowired
    private BrandService brandService;

    /***
     * 增加品牌  http://localhost:8081/brand
     */
    @PostMapping
    public RespResult add(@RequestBody Brand brand){
        // 增加品牌
        brandService.save(brand);
        return RespResult.ok();
    }

    /****
     * 修改
     */
    @PutMapping
    public RespResult update(@RequestBody Brand brand){
        //修改品牌
        brandService.updateById(brand);
        return RespResult.ok();
    }

    /****
     * 删除品牌
     */
    @DeleteMapping("/{id}")
    public RespResult delete(@PathVariable(value = "id") Integer id){
        //删除品牌
        brandService.removeById(id);
        return RespResult.ok();
    }
}

使用postman测试增删改,增删改mp提供了很多的方法,不需要自己去写,查询有条件查询,需要自己手写

在这里插入图片描述

5.2.4 条件查询/分页

条件查询需要封装条件信息,MyBatis Plus提供了条件封装对象Wrapper(它的子类QueryWrapper可以直接使用),我们可以用它的子类QueryWrapper实现封装查询条件

6.2.4.1 条件查询

BrandService中创建如下方法:

List<Brand> queryList(Brand brand);

BrandServiceImpl中创建条件查询方法实现(不要忘了注入brandMapper):

/**
 * 多条件查询
 */
@Override
public List<Brand> queryList(Brand brand) {
    // 多条件构造器
    QueryWrapper<Brand> queryWrapper = new QueryWrapper<Brand>();
    if(!StringUtils.isEmpty(brand.getName())){
        queryWrapper.like("name",brand.getName());
    }
    if(!StringUtils.isEmpty(brand.getName())){
        queryWrapper.eq("initial",brand.getInitial());
    }
    return brandMapper.selectList(queryWrapper);
}

注意:like:表示模糊查询;eq:表示等值查询

BrandController中创建条件查询方法:

/**
 * 条件查询
 */
@PostMapping(value = "/list")
public RespResult<List<Brand>> list(@RequestBody(required = false) Brand brand){
    // 查询
    List<Brand> brands = brandService.queryList(brand);
    return RespResult.ok(brands);
}
6.2.4.2 分页查询

BrandService中创建如下方法:

Page<Brand> queryPageList(Long currentPage,Long size,Brand brand);

BrandServiceImpl中创建条件查询方法实现(不要忘了注入brandMapper):

/***
 * 分页查询
 */
@Override
public Page<Brand> queryPageList(Long currentPage, Long size, Brand brand) {
    // 封装查询条件
    Page<Brand> page = brandMapper.selectPage(
            new Page<Brand>(currentPage, size),
            new QueryWrapper<Brand>()
                    .like("name", brand.getName()));
    return page;
}

BrandController中创建条件查询方法:

/**
 * 条件分页查询
 */
@PostMapping(value = "/list/{page}/{size}")
public RespResult<Page<Brand>> list(
        @PathVariable(value = "page")Long currentPage,
        @PathVariable(value = "size")Long size,
        @RequestBody(required = false) Brand brand){
    // 分页查询
    Page<Brand> brandPage = brandService.queryPageList(currentPage,size,brand);
    return RespResult.ok(brandPage);
}

测试结果如下:

在这里插入图片描述

注意:mp的分页查询,需要写分页拦截器,不然就不起作用

package com.gupaoedu.vip.mall.config;

@Configuration
public class StartConfig {

    /****
     * 分页插件(分页拦截器),必须写拦截器,不然mp的分页功能不生效
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor pageInterceptor = new PaginationInterceptor();
        // 设置数据类型
        pageInterceptor.setDbType(DbType.MYSQL);
        return pageInterceptor;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949905.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch:Lucene 2024 年回顾

作者&#xff1a;来自 Elastic Chris Hegarty 2024 年对于 Apache Lucene 来说又是重要的一年。在本篇博文中&#xff0c;我们将探讨主要亮点。 Apache Lucene 在 2024 年表现出色&#xff0c;发布了许多版本&#xff0c;包括三年来的首次重大更新&#xff0c;其中包含令人兴奋…

基于LabVIEW的BeamGage自动化接口应用

设置 National Instruments LabVIEW可执行程序需要被配置为使用.NET 4框架。.NET允许自定义可执行程序的运行方式。可通过以下方式实现&#xff1a; 在LabVIEW安装目录中创建一个名为LabVIEW.exe.config的文本文件&#xff08;例如&#xff1a;C:\Program Files\National Ins…

卸载干净 IDEA(图文讲解)

目录 1、卸载 IDEA 程序 2、注册表清理 3、残留清理 1、卸载 IDEA 程序 点击屏幕左下角 Windows 图标 -> 设置-控制面板->intellij idea 勾选第一栏 Delete IntelliJ IDEA 2022.2 caches and local history&#xff0c;表示同时删除 IDEA 本地缓存以及历史。 Delete I…

李宏毅机器学习课程笔记02 | 机器学习任务攻略General Guide

第一步&#xff1a;分析loss on training data 先检查在训练数据上模型是否很好的学习 情况1&#xff1a;如果在训练集上&#xff0c;loss很大&#xff0c;说明在训练资料上没有训练好 可能性1&#xff1a;设置的模型太简单了&#xff0c;模型存在model bias模型偏差&#x…

【C++】19.多态

文章目录 1. 多态的概念2. 多态的定义及实现2.1 多态的构成条件2.1.1 实现多态还有两个必须重要条件&#xff1a;2.1.2 虚函数 (Virtual Function)定义&#xff1a;特性&#xff1a;示例代码&#xff1a;代码分析1. 类定义部分2. 主函数部分运行结果 重点讲解1. 虚函数的作用2.…

光伏仿真与设计系统应用架构深度剖析

在光伏产业蓬勃发展的时代背景下&#xff0c;绿虫光伏仿真与设计系统成为推动其高效发展的核心力量。其应用架构涵盖多个关键步骤&#xff0c;每个环节都紧密相扣&#xff0c;共同构建起精准且高效的设计体系。 气象分析作为开篇之笔&#xff0c;起着基石般的重要作用。系统全…

进程间通讯

简介&#xff1a; 进程间通讯方式有&#xff1a; 1.内存映射&#xff08;mmap&#xff09;&#xff1a; 使用mmap函数将磁盘空间映射到内存 2.管道 3.信号 4.套接字&#xff08;socket&#xff09; 5.信号机制 通过进程中kill函数&#xff0c;去给另一个函数发送信号&a…

空压机接入配置实例:利用 MODBUS - TCP 转 Ethernet IP 网关实现连接

在工业自动化生产环境中&#xff0c;空压机作为重要的气源设备&#xff0c;其稳定运行和有效监控对于整个生产流程至关重要。然而&#xff0c;不同厂家生产的空压机可能采用不同的通信协议&#xff0c;这给集中监控和管理带来了挑战。在本次案例中&#xff0c;我们遇到的空压机…

基于 Boost.Asio 和 Boost.Beast 的异步 HTTP 服务器(学习记录)

已完成功能&#xff1a; 支持 GET 和 POST 请求的路由与回调处理。 解析URL请求。 单例模式 管理核心业务逻辑。 异步 I/O 技术和 定时器 控制超时。 通过回调函数注册机制&#xff0c;可以灵活地为不同的 URL 路由注册处理函数。 1. 项目背景 1.1 项目简介 本项目是一个基于…

Harmony开发【笔记1】报错解决(字段名写错了。。)

在利用axios从网络接收请求时&#xff0c;发现返回obj的code为“-1”&#xff0c;非常不解&#xff0c;利用console.log测试&#xff0c;更加不解&#xff0c;可知抛出错误是 “ E 其他错误: userName required”。但是我在测试时&#xff0c;它并没有体现为空&#xff0c;…

Spring源码分析之事件机制——观察者模式(二)

目录 获取监听器的入口方法 实际检索监听器的核心方法 监听器类型检查方法 监听器的注册过程 监听器的存储结构 过程总结 Spring源码分析之事件机制——观察者模式&#xff08;一&#xff09;-CSDN博客 Spring源码分析之事件机制——观察者模式&#xff08;二&#xff…

关于Mac中的shell

1 MacOS中的shell 介绍&#xff1a; 在 macOS 系统中&#xff0c;Shell 是命令行与系统交互的工具&#xff0c;用于执行命令、运行脚本和管理系统。macOS 提供了多种 Shell&#xff0c;主要包括 bash 和 zsh。在 macOS Catalina&#xff08;10.15&#xff09;之前&#xff0c…

【C++】20.二叉搜索树

文章目录 1. 二叉搜索树的概念2. 二叉搜索树的性能分析3. 二叉搜索树的插入4. 二叉搜索树的查找5. 二叉搜索树的删除6. 二叉搜索树的实现代码7. 二叉搜索树key和key/value使用场景7.1 key搜索场景&#xff1a;7.2 key/value搜索场景&#xff1a;7.3 主要区别&#xff1a;7.4 ke…

【大模型+本地自建知识图谱/GraphRAG/neo4j/ollama+Qwen千问(或llama3)】 python实战(中)

一、建立基本的知识图谱并导入neo4j 这里我举例用的属性表、关系表&#xff0c;大概格式如下 id名字颜色a1苹果红色 startrelenda1属于b1 启动neo4j&#xff08;关于neo4j的安装此处不再赘述&#xff09; import pandas as pd from py2neo import Graph, Node, Relationship…

【pyqt】(四)Designer布局

布局 之前我们利用鼠标拖动的控件的时候&#xff0c;发现一些部件很难完成对齐这些工作&#xff0c;pyqt为我们提供的多种布局功能不仅可以让排版更加美观&#xff0c;还能够让界面自适应窗口大小的变化&#xff0c;使得布局美观合理。最常使用的三种布局就是垂直河子布局、水…

解决“KEIL5软件模拟仿真无法打印浮点数”之问题

在没有外部硬件支持时&#xff0c;我们会使用KEIL5软件模拟仿真&#xff0c;这是是仿真必须要掌握的技巧。 1、点击“Project”&#xff0c;然后点击“Options for target 项目名字”&#xff0c;点击“Device”,选择CPU型号。 2、点击“OK” 3、点击“Target”,勾选“Use Mi…

【项目实战1】五子棋游戏

目录 C语言编程实现五子棋&#xff1a;&#xff1a; game.h game.c 1.打印菜单 2.打印棋盘 3.玩家下棋 4.判断五子连珠 5.判断输赢 6.游戏运行 game.c完整源代码展示 test.c C语言编程实现五子棋&#xff1a;&#xff1a; game.h #pragma once #include<stdio.h> …

用ResNet50+Qwen2-VL-2B-Instruct+LoRA模仿Diffusion-VLA的论文思路,在3090显卡上训练和测试成功

想一步步的实现Diffusion VLA论文的思路&#xff0c;不过论文的图像的输入用DINOv2进行特征提取的&#xff0c;我先把这个部分换成ResNet50。 老铁们&#xff0c;直接上代码&#xff1a; from PIL import Image import torch import torchvision.models as models from torch…

Spring Boot 项目自定义加解密实现配置文件的加密

在Spring Boot项目中&#xff0c; 可以结合Jasypt 快速实现对配置文件中的部分属性进行加密。 完整的介绍参照&#xff1a; Spring Boot Jasypt 实现application.yml 属性加密的快速示例 但是作为一个技术强迫症&#xff0c;总是想着从底层开始实现属性的加解密&#xff0c;…

A/B实验之置信检验(一):如何避免误判 (I类) 和漏报 (II类)

假设检验的依据&#xff1a;如何避免误判和漏报 A/B实验系列相关文章&#xff08;置顶&#xff09; 1.A/B实验之置信检验&#xff08;一&#xff09;&#xff1a;如何避免误判和漏报 2.A/B实验之置信检验&#xff08;二&#xff09;&#xff1a;置信检验精要 引言 在数据驱动…