累了吗项目
你怎么穿着品如的衣服?做戏就要做全套,本专题就给你做个全套,一步到胃!
一、背景
-
累了吗
是国内极具潜力的推拿按摩休闲娱乐
平台。我们将以累了吗
项目为业务背景,通过实现累了吗
平台的技师项目维护、下单、和取消订单的功能,来讲解springbootRestful
纯后端的框架搭建。
二、slogan:
- 累了别叫妈,累了就叫累了吗
三、涉及到的技术:
-
spring mvc
:controller
层接收校验数据 -
mybatis-plus
:orm
层框架,用于数据库交互,也是目前比较火第一个mybatis
的二次框架 -
docker
:用于部署项目,同时mysql
、redis
也都会部署在上面 -
redis
:用于缓存
和分布式锁
-
rabbitmq
:这些中间件
将在下一个专题讲微服务
的时候详细讲解 -
多模块
:最后拆分项目,将单模块拆分成多模块,给微服务
打个基础
四、定位
- 一个普通的
springboot
默认设置的最大线程数
是200,最大连接数
是10000,也就是说单个springboot
在不考虑速度的情况下,最多支持的并发数是10000。当然这都是理论值罢了,真实情况肯定达不到。但是通过nginx
,简单的部署一个集群,并发数几千级别还是可以的(ps:接接外包肯定不是问题的拉) - 笔者在自己团队的app拥有5w用户,在使用高峰期日活量也不过8000左右,并发数肯定就更少了。因此这样一个简单的
springboot
项目做十万用户量(非并发量)的服务器后端是可行的。如果有更高的需求,就应该往微服务
,分库分表
方面演进了,这是下一个专题的内容,这里就不赘述了
数据库设计
本专题是给大家讲springboot,因此在业务逻辑上会简单一些,总共3张表
- 商品表:对应服务项目信息,如:泡脚、推拿等
- 订单主表:对应主订单信息,主订单上保存下单时间、下单人、支付状态等信息
- 订单详情:与主订单是一对多的关系,订单详情上的
order_id
用于关联主订单,product_id
用于关联对应商品 - 除此之外,每个表的主键使用18位自增策略。同时拥有创建人、创建时间、修改人、修改时间(自动填充)
-- 商品
create table `product_info`
(
`product_id` int(18) not null AUTO_INCREMENT comment '商品主键',
`product_name` varchar(64) not null comment '商品名称',
`product_price` decimal(8,2) not null comment '单价',
`product_description` varchar(256) comment '描述',
`product_status` tinyint(3) DEFAULT '0' COMMENT '商品状态,0正常1下架',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`create_user` varchar(10) not null comment '创建人',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
`update_user` varchar(10) not null comment '修改人',
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单
create table `order_master`
(
`order_id` int(18) not null AUTO_INCREMENT comment '订单主键',
`buyer_name` varchar(32) not null comment '买家名字',
`buyer_phone` varchar(32) not null comment '买家电话',
`order_amount` decimal(8,2) not null comment '总金额',
`status` tinyint(3) not null default '0' comment '订单状态',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`create_user` varchar(10) not null comment '创建人',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
`update_user` varchar(10) not null comment '修改人',
primary key (`order_id`),
key `idx_buyer_openid` (`buyer_phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单详情
create table `order_detail`
(
`detail_id` int(18) not null AUTO_INCREMENT comment '详情主键',
`order_id` int(18) not null comment '订单主键',
`product_id` int(18) not null comment '商品主键',
`product_name` varchar(64) not null comment '商品名称',
`product_price` decimal(8,2) not null comment '当前价格',
`product_number` int not null comment '数量',
`create_time` timestamp not null default current_timestamp comment '创建时间',
`create_user` varchar(10) not null comment '创建人',
`update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间',
`update_user` varchar(10) not null comment '修改人',
primary key (`detail_id`),
key `idx_order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Git项目使用
码云地址:https://gitee.com/chaitou/leilema.git
一、克隆项目
直接clone就完事了,简直不要太容易
二、运行代码
稍等片刻…如果没配过国内maven加速镜像的,估计是要好一会…等项目导入成功后,启动试试,跟上节说的方法是一样的
无法运行原因很可能是数据库无法连接:
①由于笔者的目前旧的服务器202006会到期,到期后项目可能无法重新启动,笔者到时会更新最新服务器地址,注意更新最新代码。
②建议通过项目sql
目录下的语句自己配置mysql数据库,同时修改application.yml
下的数据库连接。最好学习使用一下docker部署mysql,这是程序员必备技能,抽空一小时学习一下,受益颇深
ps:数据库是免费提供给大家学习的,请学习使用完后清除自己生成的数据!同时禁止提交涉黄、反动等数据!
三、恢复到指定历史版本(重点)
因为代码不断更新,因此读者可能希望回退到指定的版本,对照文章进行学习,才不会被后续的代码干扰。操作并不难
1. 查看历史版本
2. 指定历史版本生成新分支
3. 切换分支
完全可以拉取多个版本的分支,在之间互相切换
准备插件
一、请求工具
在第一节中,要想访问hello world
接口,需要到浏览器上输入http://localhost:8081/hello
进行验证。get
请求倒是可行,如果post
请求,且参数较多,再甚至要设置cookie
等信息头的时候,浏览器就不能胜任了。最为开发人员,接口总是要测试的。因此介绍一下请求工具,主流方式主要有2种:
- 通过
Postman
或其他模拟请求的工具,编写请求 - 集成
swagger
框架,通过在controller
层写注解指明请求参数,最后通过swagger
暴露出来的页面进行模拟请求。优点是可以省去手动编写请求,以及API文档。缺点是有代码入侵性,需要在代码上加上swagger
代码
由于个人不是很喜欢有代码侵入性风格的swagger
,因此选择使用postman
这种模拟请求的工具。关于这一块,我介绍2个工具,现实开发中也经常用到:
-
RestfulToolkit
:这是IDEA的一款插件,比起postman
优势:①其嵌入在IDEA中,触手可得②该工具可以自动发现controller
层的相关请求,不用自己手动写地址或参数;而缺点:①毕竟知识一个小插件,就100k的大小,不能给请求做分组②请求参数也无法保存③与团队分享也不是那么友好 -
postman
:这个应该很多人都听说过了,比起RestfulToolkit
,优点就是可以分组,可以保存请求,很方便的做团队API的分析,缺点也与上面的互补
介绍了2款插件,不存在孰优孰劣,我习惯开发的时候使用RestfulToolkit
,快准狠,提高开发效率。而负责的请求以及测试环境,则习惯用postman
编写,利于保存分享
RestfulToolkit
使用也贼简单
postman
postman比较复杂,专门写了一片文章,请参考:postman入门
二、Lombok插件
相信你肯定写过下面的代码
-
getter
跟setter
,明明每个类都一样,为什么就是要一直写呢?就算可以自动生成也很麻烦,属性一多,特别是修改属性类型或者修改属性名时,简直想打人 - 打日志每次都写
private static final Logger logger= LoggerFactory.getLogger(OrderAddVo.class);
这一句,还有一些小白不加static
不加final
的…
这些代码明明都一个样,吃饱撑着折磨自己?于是就有人发明了lombok
,只要在类上面加上@Data
就会在代码编译时自动帮你写上getter
跟setter
、写上@Slf4j
那就自动帮你写logger
、还有其他equals
等功能。自从用少了lombok
,写代码也变快了,头发掉的少了,代码也简洁了
public class OrderAddVo {
private static final Logger logger= LoggerFactory.getLogger(OrderAddVo.class);
/**
* 买家名字
*/
@NotBlank(message = "买家姓名不能为空")
private String buyerName;
/**
* 买家电话
*/
@NotBlank(message = "买家电话不能为空")
private String buyerPhone;
@NotBlank(message = "订单详情不能为空")
private String orderDetails;
public String getBuyerName() {
return buyerName;
}
public void setBuyerName(String buyerName) {
this.buyerName = buyerName;
}
public String getBuyerPhone() {
return buyerPhone;
}
public void setBuyerPhone(String buyerPhone) {
this.buyerPhone = buyerPhone;
}
public String getOrderDetails() {
return orderDetails;
}
public void setOrderDetails(String orderDetails) {
this.orderDetails = orderDetails;
}
}
但是有利必有弊,我们想用lombok
,就必须添加lombok
的依赖
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
同时还得添加lombok
的插件,否则IDEA会报错(这也是最大的弊端,一旦你使用了lombok
,那么所有运行该代码的人都得装lombok
插件,这里就不讨论利弊取舍了,我们就用了)安装跟上面一样,就是搜索一下,然后安装就行了