目录

  • 一、背景
  • 二、数据库
    • 1.1、创建数据库
    • 1.2、创建表
    • 1.3、初始数据
    • 1.4、配置中心数据
  • 三、domain-stock
    • 3.1、实体类
    • 3.2、持久层
    • 3.3、打包到私服
  • 四、maven依赖
  • 五、编码
    • 5.1、controller
    • 5.2、service
    • 5.3、dto
  • 六、配置
    • 6.1、主类
    • 6.2、bootstrap.properties
    • 6.3、ebean.properties
    • 6.4、build.properties
    • 6.5、dozerMapping.xml
  • 七、验证

一、背景

  既然我们已经搭建了配置中心了,也实现了自定义的 db starter 和公共的 API starter ,现在我们就把它整合到一起,完成一个库存系统的设计,你就可以感受到简单了。

二、数据库

1.1、创建数据库

#创建库
create databases stock;
CREATE DATABASE IF NOT EXISTS stock
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_general_ci;

  字符集推荐使用: utf8mb4

1.2、创建表

#创建一个库存表
CREATE TABLE `tb_goods_stock` (`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',`goods_id` int unsigned NOT NULL DEFAULT '0' COMMENT '商品id',`inventory` int unsigned NOT NULL DEFAULT '0' COMMENT '库存',`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',PRIMARY KEY (`id`),KEY `idx_goods_id` (`goods_id`),KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COMMENT='库存表';

1.3、初始数据

#插入商品编号为10001和10002的库存分别为100,200
insert into tb_goods_stock(goods_id,inventory) values(10001,100);
insert into tb_goods_stock(goods_id,inventory) values(10002,200);

1.4、配置中心数据

三、domain-stock

3.1、实体类

GoodsStock.java

package cn.alian.domain.stock.domain;import lombok.Getter;
import lombok.Setter;import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;@Setter
@Getter
@Entity
@Table(name = "tb_goods_stock")
public class GoodsStock implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name = "id", insertable = false, nullable = false)private Integer id;/*** 商品id*/@Column(name = "goods_id", nullable = false)private int goodsId;/*** 库存数量*/@Column(name = "inventory", nullable = false)private int inventory;/*** 创建时间*/@Column(name = "create_time", nullable = false, insertable = false, updatable = false)private LocalDateTime createTime;/*** 更新时间*/@Column(name = "update_time", nullable = false, insertable = false, updatable = false)private LocalDateTime updateTime;}

3.2、持久层

GoodsStockRepository.java

package cn.alian.domain.stock.repository;import cn.alian.domain.stock.domain.GoodsStock;
import org.springframework.data.ebean.repository.EbeanRepository;
import org.springframework.stereotype.Repository;@Repository
public interface GoodsStockRepository extends EbeanRepository<GoodsStock, Integer> {}

3.3、打包到私服

  通过maven自动生成Ebean QueryBean,之前的文章说了,就不再列出了,具体可以参考:(四)Alian 的 Spring Cloud Ebean自动生成Query Bean

四、maven依赖

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>cn.alian.microservice</groupId><artifactId>parent</artifactId><version>1.0.0-SNAPSHOT</version></parent><groupId>cn.alian.mall</groupId><artifactId>stock</artifactId><version>1.0.0-SNAPSHOT</version><name>stock</name><description>库存服务</description><dependencies><!--自定义的db starter--><dependency><groupId>cn.alian.microservice</groupId><artifactId>common-db</artifactId><version>1.0.0-SNAPSHOT</version></dependency><!--自定义的API starter--><dependency><groupId>cn.alian.microservice</groupId><artifactId>common-api</artifactId><version>1.0.0-SNAPSHOT</version></dependency><!--domain Query Bean--><dependency><groupId>cn.alian.domain</groupId><artifactId>domain-stock</artifactId><version>1.0.0-SNAPSHOT</version></dependency><!--配置中心--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency><!--注册中心--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!--sql日志输出--><dependency><groupId>com.googlecode.log4jdbc</groupId><artifactId>log4jdbc</artifactId></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency></dependencies><repositories><repository><id>nexus-repos</id><name>Team Nexus Repository</name><url>http://192.168.0.210:8081/nexus/content/groups/public</url></repository><repository><id>nexus-repos-snapshots</id><name>Team Nexus Repository Snapshots</name><url>http://192.168.0.210:8081/nexus/content/groups/public-snapshots</url></repository><repository><id>aliyun-maven-repo</id><url>https://maven.aliyun.com/repository/public</url></repository></repositories><pluginRepositories><pluginRepository><id>nexus-repos</id><name>Team Nexus Repository</name><url>http://192.168.0.210:8081/nexus/content/groups/public</url></pluginRepository><pluginRepository><id>nexus-repos-snapshots</id><name>Team Nexus Repository Snapshots</name><url>http://192.168.0.210:8081/nexus/content/groups/public-snapshots</url></pluginRepository></pluginRepositories></project>

五、编码

5.1、controller

StockController.java

package cn.alian.mall.stock.controller;import cn.alian.mall.stock.dto.DeductInventoryRequestDto;
import cn.alian.mall.stock.dto.DeductInventoryResponseDto;
import cn.alian.mall.stock.service.StockService;
import cn.alian.microservice.common.dto.ApiResponseDto;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;@Slf4j
@Validated
@RestController
@RequestMapping({"/api/v1/stock"})
@Api(description = "库存相关接口")
public class StockController {@Autowiredprivate StockService stockService;@ApiOperation("扣减商品库存")@PostMapping("/deductInventory")public ApiResponseDto<DeductInventoryResponseDto> request(@ApiParam @Valid @RequestBody DeductInventoryRequestDto dto) {log.info("扣减商品库存请求信息:{}", JSON.toJSONString(dto));DeductInventoryResponseDto responseDto = new DeductInventoryResponseDto();Pair<Boolean, String> pair = stockService.deductInventory(dto.getGoodsId(), dto.getNum());log.info("扣减库存返回的结果:{}", pair.getRight());responseDto.setResultCode(pair.getLeft() ? "0000" : "9999");responseDto.setMessage(pair.getRight());return ApiResponseDto.success(responseDto);}
}

5.2、service

StockService.java

package cn.alian.mall.stock.service;import io.ebean.DB;
import io.ebean.EbeanServer;
import io.ebean.SqlUpdate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Slf4j
@Service
public class StockService {@Autowiredprivate EbeanServer ebeanServer;public Pair<Boolean, String> deductInventory(int goodsId, int num) {String sql = "update tb_goods_stock set inventory=inventory - " + num + " where goods_id =" + goodsId;SqlUpdate sqlUpdate = DB.sqlUpdate(sql);int execute = sqlUpdate.execute();log.info("商品【{}】库存操作完成", goodsId);if (execute != 0) {return Pair.of(true, "库存扣减成功");}return Pair.of(false, "库存扣减失败");}}

5.3、dto

DeductInventoryRequestDto.java

package cn.alian.mall.stock.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.validation.constraints.NotNull;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@ApiModel(description = "扣减库存请求信息")
public class DeductInventoryRequestDto {@NotNull@ApiModelProperty("订单id")private Integer orderId;@NotNull@ApiModelProperty("商品id")private Integer goodsId;@NotNull@ApiModelProperty("数量")private Integer num = 1;}

DeductInventoryResponseDto.java

package cn.alian.mall.stock.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.validation.constraints.NotNull;@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@ApiModel(description = "扣减库存返回信息")
public class DeductInventoryResponseDto {@NotNull@ApiModelProperty("结果码")private String resultCode;@NotNull@ApiModelProperty("结果说明")private String message;}

六、配置

6.1、主类

StockApplication.java

package cn.alian.mall.stock;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@EnableDiscoveryClient
@SpringBootApplication
public class StockApplication {public static void main(String[] args) {SpringApplication.run(StockApplication.class, args);}}

6.2、bootstrap.properties

bootstrap.properties

#应用名
spring.application.name=stock
#开发环境
spring.profiles.active=dev
#配置标签(根据配置中心,本文全是采用master)
spring.cloud.config.label=master
#配置中心地址,多个用逗号分隔
spring.cloud.config.uri=http://10.130.3.222:6666
#设置为true时,如果服务无法连接到配置中心服务器,则服务启动失败
spring.cloud.config.fail-fast=true
#日志配置,通过配置中心获取
logging.config=${spring.cloud.config.uri}/logback/${spring.application.name}.xml

6.3、ebean.properties

ebean.properties

ebean.packages=cn.alian.domain.stock

6.4、build.properties

build.properties

build.groupId=${pom.groupId}
build.artifactId=${pom.artifactId}
build.version=${pom.version}
# 生成的文档说明
build.description=${pom.description}
# spring-boot:run -Ppack时方便生成api客户端
build.pack=cn.alian.mall.stock

6.5、dozerMapping.xml

dozerMapping.xml

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd">
</mappings>

七、验证

  我们公共的API已经完成了swagger的整合,我们启动项目使用swagger进行测试

返回结果:

{"code": "0000","msg": "success","content": {"resultCode": "0000","message": "库存扣减成功"},"timestamp": 1649741434665,"bizCode": null,"bizMsg": null,"success": true
}

数据库结果:

mysql> select * from tb_goods_stock;
+----+----------+-----------+-------------------------+-------------------------+
| id | goods_id | inventory | create_time             | update_time             |
+----+----------+-----------+-------------------------+-------------------------+
|  1 |    10001 |        99 | 2022-04-06 11:25:51.626 | 2022-04-12 05:30:35.662 |
|  2 |    10002 |       200 | 2022-04-12 01:56:39.974 | 2022-04-12 01:56:39.974 |
+----+----------+-----------+-------------------------+-------------------------+
2 rows in set (0.00 sec)

  从结果上来说吗,我们的系统已经通过测试了。后续我们会生成接口调用,供订单系统调用。

(十)Alian 的 Spring Cloud 库存系统相关推荐

  1. (十八)Alian 的 Spring Cloud Gateway 集群配置

    目录 一.简介 二.配置 三.配置文件 3.1.application.properties 四.主类 五.部署及配置 5.1.部署 5.2.Nginx配置 5.3.Spring Cloud Gate ...

  2. (十五)Alian 的 Spring Cloud 自动生成项目

    目录 一.创建 1.1.第一步 二.mvn命令 三.生成项目 3.1.配置 3.1.属性配置 3.2.控制层 3.3.服务层 四.验证 4.1.请求生成项目 4.2.生成项目结果 4.3.项目结构 一 ...

  3. (十一)Alian 的 Spring Cloud 文档中心(swagger聚合文档)

    目录 一.简介 1.1.maven依赖 二.核心配置类 2.1.SwaggerUI配置 2.2.服务定义的上下文 2.3.定时刷下文档定义 2.4.文档接口 三.配置 3.1.主类 3.2.boots ...

  4. (七)Alian 的 Spring Cloud Config 配置中心(客户端)

    目录 一.背景 二.maven依赖 三.配置文件 四.验证 一.背景   通过上一篇文章,我们已经搭建了配置中心了,接下里我们继续改造我们的订单服务了,之前我们的订单服务的数据库配置还是写在配置文件中 ...

  5. (三)Alian 的 Spring Cloud Eureka Server(服务注册中心)

    目录 一.创建Eureka服务工程 1.1.第一步(创建工程) 1.2.第二步(springboot工程) 1.3.第三步(工程设置) 1.4.第四步(依赖选择) 二.配置 2.1.pom文件 2.2 ...

  6. (十四)Alian 的 Spring Cloud 订单服务调用自动生成的API

    目录 一.背景 二.maven依赖 三.主要编码 3.1.控制层 3.2.服务层 3.3.dto 3.4.主类 四.配置 4.1.bootstrap.properties 4.2.build.prop ...

  7. (十九)Alian 的 Spring Cloud Config 集群配置

    目录 一.简介 1.1.第一步 二.maven依赖 三.配置 3.1.application.properties 3.2.主类 四.客户端修改(支付系统) 4.1 maven依赖 4.2 支付系统主 ...

  8. (十六)Alian 的 Spring Cloud Eureka 集群配置(主机名方式)

    目录 一.背景 二.maven依赖 三.主类 四.Eureka服务配置 五.启动服务 5.1 服务1效果图(eureka-server1.com) 5.2 服务2效果图(eureka-server2. ...

  9. (十二)Alian 的 Spring Cloud 自定义Archetype

    目录 一.简介 1.1.archetype目录结构 1.2.Archetype Domain结构图 1.3.Archetype Project结构图 二.Archetype Project 2.1.项 ...

最新文章

  1. 设有一数据库,包括四个表:学生表(Student)、课程表(Course)、成绩表(Score)以及教师信息表(Teacher)。...
  2. XP 的共享方案(面对新人)
  3. The import java.util cannot be resolved The import javax.servlet cannot be resolved
  4. JVM内存管理机制线上问题排查
  5. win10上安装opencv详细教程
  6. 【收藏】Win10:路径长度超过260个字符
  7. 使用遥控器控制汽车,实现高难度的泊车(发明畅想)
  8. MapReduce的方式进行HBase向HDFS导入和导出
  9. 西部数据硬盘支持linux,西部数据开发新的Linux文件系统“Zonefs” 支持在分区块设备上运行...
  10. 200(强缓存)和304(协商缓存)的区别
  11. 【原创】C# Sealed、new、virtual、abstract、override的理解
  12. php中的id怎么传值,uniapp如何跳转页面传值
  13. Highcharts+Spring饼图使用实例
  14. 排序算法(一)--桶排序、冒泡、快排(JAVA)
  15. Oracle 归档开启切换和归档日志删除(单实例和RAC)
  16. 【转】webkit webApp 开发技术要点总结
  17. ES6、7学习笔记(尚硅谷)-3-变量的解构赋值
  18. MPLAB X环境ICD3无法使用
  19. 精进Spring—Spring常用注解【经典总结】
  20. intellij idea 无法识别新装字体的问题的两种解决办法

热门文章

  1. 亚马逊运营之关键词排名问题的思考!
  2. 数据结构-使用c语言 朱战立 pdf,数据结构-使用C语言朱战立.ppt
  3. 廖雪峰官网自学python 基础类型(附练习题答案)
  4. 十几年老员工提出的五条有效沟通的建议
  5. 每日定点将excel数据批量插入mysql数据库对应表
  6. VideoPlayer的方法机翻
  7. 基于php学生信息管理系统
  8. ffmpeg 视频编码三(基于 libavfilter 转换视频)
  9. 一篇文章畅游在C语言基础知识学习的海洋中(持续更新中……)
  10. 前端基础复习-HTML