简介
技术选型
展示项目中使用到的技术框架和中间件。
用户层:node.js Vue.js ElementUI 微信小程序 apache echarts
网关层:nginx
应用层:Spring Boot Spring MVC Spring Task httpclient Spring Cache JWT 阿里云OSS Swagger POI WebSocket
数据库:MySQL Redis mybatis pagehelper spring data redis
工具:Git maven junit postman
后端环境搭建
熟悉项目的整体结构
sky-take-out maven父工程,统一管理依赖版本,聚合其他子模块
sky-common 子模块,存放公共类,例如:工具类,常量类,异常类等
sky-pojo 子模块,存放实体类,VO,DTO等
sky-server 子模块,后端服务,存放配置文件,controller、service、mapper
关于什么是DTO、VO、entity?
entity 实体,通常与数据库中的表对应
DTO 数据传输对象,通常用于程序中各层之间传递数据
VO 视图对象,为前端展示数据提供对象
POJO 普通java对象,只有属性和对应的getter和setter
如何实用git进行版本管理?
Git对待数据的方式并非差异比较,而是采用快照的方式。Git把数据看作是对小型文件系统的一组快照。每次提交更新或者在Git中保存状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git不再重新存储该文件,二十保留一个人链接指向之前存储的文件。Git对待数据更现实一个快照流。
Git的三种状态
- 已提交(committed):数据已经安全的保存在本地数据库中。
- 已修改(modified):已经修改了文件,但是还没有保存在数据库中。
- 已暂存(staged):表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
由此引入Git项目的三个工作区域的概念:Git仓库、工作目录、和暂存区。
Git常用命令
获取git仓库
从现在目录中初始化仓库
git init
从服务器中克隆一个现有的git仓库
git clone [url]
提交更新
git commit -m "代码提交信息"
推送到远程仓库:
git remote add origin <server>
将改动提交到远程仓库(可以将master换成你想要推送的任何分支)
git push origin master
撤销操作
git commit --amend
Git分支
分支是用来将特性开发绝缘开来的。在你创建仓库的时候,master是默认分支。在其他分支上进行开发。完成后再将他们合并到主分支上。
创建一个名字叫做test的分支
git branch test
切换当前分支到test(当你切换分支的时候,Git会重置你的工作目录,使其看起来像回到了你在分支上最后一次提交的样子。Git会自动添加、修改、删除文件以确保此时你的工作目录和这个分支最后一次提交时的样子一摸一样)
git checkout test
你可以直接这样创建分支并切换过去
git checkout -b feature_x
切换到主分支
git checkout master
合并分支
git merge test
把新建的分支删除掉
git push origin
数据库环境搭建
employee 员工表; category 分类表;
dish 菜品表; dish_flavor 菜品口味表;
setmeal 套餐表; setmeal_dish 套餐菜品关系表
user 用户表; adress_book 地址表;
shopping_cart 购物车表; orders 订单表;
order_detail 订单明细表;
Nginx反向代理和负载均衡
前端发送的请求,是如何请求到后端服务的?
nginx反向代理就是将前端发送的请求由nginx动态转发到后端服务器。
nginx反向代理好处
- 提高访问速度
- 进行负载均衡
- 保证后端服务安全
Day1
完善登录功能
password = DigestUtils.md5DigestAsHex(password.getBytes());
Swagger介绍和使用
后端生成接口文档并且进行测试
介绍
生成接口文档以及在线调试。
Knife4j是为java MVC框架集成Swagger生成Api文档的增强解决方案。
Yapi是设计阶段的工具,管理和维护接口;Swagger在开发阶段使用的框架,帮助后端开发人员做后端的接口测试。
使用方式
- 导入knife4j的maven坐标
- 在配置类中加入knife4j相关配置
- 设置静态资源映射,否则接口文档页面无法显示
- 访问接口文档界面localhost:8080/doc.html
常用注解
@Api 用在类上,例如controller表示对类的说明
@ApiModel 用在类上,例如entity,DTO,VO
@ApiModelProperty 用在属性上,描述属性信息
@ApiOPeration 用在方法上,例如controller的方法,说明方法的用途、作用
Day2
员工管理
新增员工
- 如果传入的数据是json需要添加 @RequestBody 注解
-
对象属性拷贝由A拷贝到B,前提是A,B的属性名一致
BeanUtils.copyProperties(employeeDTO,employee);
代码完善:
录入的用户名已存在,抛出异常后没有处理;
处理过程首先捕捉出现的异常,然后分析相关错误;
新增员工时,创建人id和修改人id设置为了固定值;
- 熟悉关于基于JWT令牌认证的过程。
- 截取JWT令牌,并且分析令牌里面出现的ID
- 那么如何将ID传给服务?
ThreadLocal并不是一个Thread,而是Thread的局部变量。
ThreadLocal为每一个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问到。
ThreadLocal常用方法
- public void set(T value) 设置当前线程的线程局部变量的值
- public T get() 返回当前线程所对应的线程局部变量
- public void remove()移除当前线程的线程局部变量
员工分页查询
- Pagehelper插件,分页查询是基于SQL的limit关键字计算,其返回类型也要为Page
PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());
- 分页查询XML书写:
启用禁用员工账号
@PathVariable
是Spring框架中的一个注解,用于将URL中的路径变量绑定到方法参数上。
编辑员工
- 注意书写SQL的语法错误
导入分类模块功能代码
菜品管理
公共字段自动填充
实现思路
insert create_time 创建时间 datetime
create_user 创建人id bigint
insert/update
update_time 创建时间 datetime
update_user 修改时间 bigint
- 自定义注解AutoFill,用于标识需要进行公共字段自动填充的方法。
- 自定义切面AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值。
- 在Mapper加入AutoFill注解。
//获取到当前被拦截的方法上的数据库操作类型
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//方法签名对象
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);//获得方法上的注解
OperationType operationType = autoFill.value();//获得数据库操作类型
//获取到当前被拦截的方法的参数--实体对象
Object[] args = joinPoint.getArgs();
if(args == null || args.length == 0){
return;
}
Object entity = args[0];
//准备赋值的数据
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();
//根据当前不同的操作类型,为对应的属性通过反射来赋值
if(operationType == OperationType.INSERT){
//为四个字段赋值
try{
Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser",Long.class);
Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser",Long.class);
//通过反射赋值
setCreateTime.invoke(entity,now);
setCreateUser.invoke(entity,currentId);
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
}catch (Exception e){
e.printStackTrace();
}
}else if (operationType == OperationType.UPDATE){
try{
Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser",Long.class);
//通过反射赋值
setUpdateTime.invoke(entity,now);
setUpdateUser.invoke(entity,currentId);
}catch (Exception e){
e.printStackTrace();
}
}
通过在Mapper里面加入注解
@AutoFill(value = OperationType.INSERT)
/@AutoFill(value = OperationType.UPDATE)
使用阿里OSS
- 在阿里云官网创建一个bucket
- 完善配置项
- 创建config文件
Day5
Redis基础知识
Redis是基于内存的key-value结构数据库。
- 基于内存存储,读写性能高
- 适合存储热点数据,热点商品、资讯、新闻
- 企业应用广泛
如何打开Redis在程序所在的文件目录打开cmd
redis-server.exe redis.windows.conf
结束进程
ctrl + c
如何连接redis
redis-cli.exe
Redis中的数据类型
Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型。
- 字符串string
- 哈希hash
- 列表list
- 集合set
- 有序集合sorted set / zset
字符串String
SET key value 设置指定key的值;
GET key 获取指定key的值;
SETEX key seconds value 设置指定key的值,并将key的过期时间设为seconds(获取验证码)
SETNX key value 只有在key不存在时设置key的值
哈希操作命令
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
HSET key field value 将哈希表key中的字段field的值设为value
HGET key field 获取存储在哈希表中指定字段的值
HDEL key field 删除存储在哈希表中的指定字段
HKEYS key 获取哈希表中所有字段
HVALS key 获取哈希表中所有值
其中,key、field1、value均为字符串。
列表操作命令
Redis列表是最简单的字符串列表,按照插入顺序排序,常用命令:
- LPUSH key value1 [value2] 将一个或多个值插入到列表头部
- LRANGE key start stop 获取列表最后一个元素 lrange key 0 -1输出全部元素
- LPOP key 移除并获取列表最后一个元素
- LLEN key 获取列表长度
- R类似
集合操作命令
Redis set 是string 类型的无序集合。集合成员是唯一的,集合中不能出现重复的数据,常见命令:
- SADD key member1 [member2] 向集合中添加一个或多个成员
- SMEMBERS key 返回集合中的所有成员
- SCARD key 获取集合的成员数
- SINTER key1 [key2] 返回给定所有集合的交集
- SUNION key1 [key2] 返回所有给定集合的并集
- SREM key member1 [member2] 删除集合中一个或多个成员
有序集合操作命令
Redis有序集合是string类型元素的集合,且不允许有重复成员。每个元素都会关联一个double类型的分数。常用命令:
ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间的成员
ZINCRBY key increment member 有序集合中对指定成员的分数加上增量increment
ZREM key member [member ...] 移除有序集合中的一个或多个成员
Redis通用命令
不分数据类型,都可以使用的命令
- KEYS pattern 查找所有符合给定模型的key
- EXISTS key 检查给定key是否存在
- TYPE key 返回key所存储的值的类型
- DEL key 该命令用于在key存在时删除key