java入门——仓库管理系统

java入门——仓库管理系统,第1张

java入门——仓库管理系统

文章目录
  • 写在前面
  • 需求说明
    • 阶段1需求
    • 阶段2需求
    • 阶段3需求
    • 阶段4需求
    • 阶段5需求
    • 阶段6需求
  • 实现
    • 数据库设计
    • 接口编写
    • jmeter测试
    • 使用@cacheable注解
    • 改为纯Redis
    • 改为kafka
    • jwt方案
    • nginx使用
    • ES学习
    • 改为ES

写在前面

本文是我毕业后入职的第一家公司的第一周入职培训所布置的任务,主要是考察一些java的基础知识,以及一些数据库的基本使用,文章过于入门,请大佬走开。

需求说明 阶段1需求
  1. 纯后台,不需要前端
  2. 增加接口,增加商品(商品名称、商品型号、生产厂家、添加时间、商品编号(主键)、商品状态[未售出、已售出]),其中商品编号用雪花算法生成
  3. 增加接口,商品查询(查询条件为 商品名称[商品型号][生产厂家]或根据商品编号直接查询),考虑复合索引
  4. 增加接口,售出商品(商品名称、商品型号、添加时间),编辑商品状态即可
  5. 使用jmeter测试效果,录入10W个商品,同时售出5W个商品
  6. 使用springboot+mybatis+mysql8+swagger

阶段1主要是springboot对mysql数据库的基础 *** 作吧,这部分还是比较简单。

阶段2需求
  1. 纯后台,不需要前端将商品查询接口改为redis缓存,加入@cacheable注解
  2. 了解redis的五种数据结构及常用命令

阶段2就加几个注解,背会儿redis相关的东西吧

阶段3需求
  1. 将之前的系统改造为纯redis实现
  2. 引入lambda stream

阶段3就是由对mysql数据库 *** 作改为对redis数据库的 *** 作

阶段4需求
  1. 学习什么是MQ,什么是kafka、生产者、消费者组、消费者、topic、partition、单播广播,及kafka原理
  2. 增加商品改为kafka生产,多线程入库
  3. 售出商品改为kafka消费,多线程出库

这个阶段就是改成使用kafka来当做"数据库"了吧,除此之外经理还让我下去了解以下这几个问题,也记录上吧。。。
问题1:什么是MQ?
问题2:什么是kafka
问题3:生产者
问题4:消费者组
问题5:消费者
问题6:topic
问题7:partition
问题8:单播广播
问题9:kafka原理。

阶段5需求
  1. 了解分布式系统中session的解决方案(客户端或服务端)
  2. 增加登录接口,jwt方案
  3. 部署2-3个程序,前置nginx,验证jwt,给出验证方案

这个阶段我就属实看不懂了,在学校也都单机没研究过分布式问题。。。

阶段6需求
  1. 学习Elasticsearch
  2. 程序全改用ES,入10w卖5W

又改数据库了吧。。不过最后还是都了解到了redis,kafka主要作为中间件,作为缓存、暂时存放的数据库,ES作为主要用来查询的数据库。同样针对这个阶段的需求1,经理提出了以下问题
问题1:shard分片 replicas副本 index template索引模板 常见数据类型
问题2:luence 与 ES的关系
问题3:ELK是什么以及三个的关系
问题4:ES存储 字符串 有哪两种数据类型,这两种的区别以及原理【重要】
问题5:ES检索(query)与过滤(filter)的区别是什么(本质)(问题3关联)
问题6:DSL基本语法(K)–查询仓库中所有状态为已售出的数据10W(分页 浅?深?)
问题7:ES分页 浅分页 深分页 区别是什么,怎么用
问题8:bulkbulk processor是什么,什么时候用)(刁钻问题 bulk和bulk processor的区别)
问题9:官方JAVA CLIENT(highLevel client/lowLevel client 区别)

实现 数据库设计

第一天,开始整吧,首先设计数据库,需求中方括号指的是可选条件。
一些基本类型,状态是枚举,主键使用雪花算法。之后是根据查询条件建立联合索引。

DROp TABLE IF EXISTSmy_stock`;

CREATE TABLE my_stock (
id bigint NOT NULL COMMENT ‘商品编号’,
goods_name varchar(100) DEFAULT NULL COMMENT ‘商品名称’,
goods_type varchar(100) DEFAULT NULL COMMENT ‘商品型号’,
manufacturer varchar(100) DEFAULT NULL COMMENT ‘生产厂家’,
add_date datetime DEFAULT NULL COMMENT ‘添加时间’,
status tinyint DEFAULT NULL COMMENT ‘商品状态’,
PRIMARY KEY (id),
UNIQUE KEY goods_unique_indeies (goods_name,goods_type,add_date) USING BTREE,
KEY goods_indeies (goods_name,goods_type,manufacturer) USING BTREE,
KEY goods_indeies1 (goods_name,manufacturer) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`

之后是编写实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Goods implements Serializable {

    
    private Long id;

    
    private String goodsName;

    
    private String goodsType;

    
    private String manufacturer;

    
    private Status status;

    
    private Date addDate;
}

商品状态是0未售出,1已售出的枚举,过于简单就不放代码了
不过主要是要实现TypeHandler来让数据库更方便的储存枚举(mybatisplus直接使用一个注解就好了)

@MappedJdbcTypes(JdbcType.TINYINT)
public class StatusHandle extends baseTypeHandler {

    
    @Override
    public void setNonNullParameter(PreparedStatement ps,int i,Status param,JdbcType jt) throws SQLException {
        ps.setInt(i,param.getStateCode());
    }

    
    private Status getState(int code){
        if(code==0||code==1){
            return Status.getStateByCode(code);
        }
        return null;
    }

    
    @Override
    public Status getNullableResult(ResultSet rs,String columnName) throws SQLException{
        int statuscode=rs.getInt(columnName);
        return getState(statuscode);
    }

    
    @Override
    public Status getNullableResult(ResultSet rs,int columnName) throws SQLException{
        int statuscode=rs.getInt(columnName);
        return getState(statuscode);
    }

    
    @Override
    public Status getNullableResult(CallableStatement cs, int columnName) throws SQLException{
        int statuscode=cs.getInt(columnName);
        return getState(statuscode);
    }
}

其次是最好是类名与字段名与数据库的一致
最后是雪花算法,说实话当时看到需求根本不认识雪花算法,心里还咯噔一下。
之后了解到雪花算法其实就是指使用64位bit作为唯一id,因为在分布式模式中全局唯一id是非常重要的
其中第一位没有意义,统一为0,之后41位是时间戳,之后10位分别是机房的5位id和机器的5位id。然后一个机房的一个机器在一毫秒内可能生成多个id,所以最后12位就区分这种情况。
既然知道了原理,之后我们从网上copy一个雪花算法工具类就行了。。。。

接口编写

基本的增删改查。
首先是添加:
请求类DTO为

@Data
@ApiModel(description = "商品")
public class GoodsDTO implements {

    @ApiModelProperty(value = "商品名称")
    @NotBlank(message = "商品名称不能为空")
    private String goodsName;

    @ApiModelProperty(value = "商品类型")
    private String goodsType;

    @ApiModelProperty(value = "生产厂家")
    private String manufacturer;
}

id由内部雪花算法生成,添加时间为调用接口时间,售出状态刚添加肯定为未售出。如果有枚举作为入参的需求可以看这篇 枚举反序列化
之后是mapper的insert语句

    
        INSERT INTO my_stock
        VALUES (#{id}, #{goodsName}, #{goodsType}, #{manufacturer}, #{addDate}, #{status})
    

然后是查询商品,这个阶段最难的地方,主要是可以通过各种条件进行查询,所以当时写mapper还整了挺久的