苍穹外卖

POJO :又分为了 Entity DTO VO

1、GIT
在idea创建git 再点击对勾, 再点击绿色指向的, 传到gitee

2、进行MD5加密 DigestUtils.md5DigestAsHex getBytes()是将password输出为编码格式iso-8859-1
password = DigestUtils.md5DigestAsHex(password.getBytes());
3、swagger 主要帮助后端做接口测试
Knife4j对swagger进行增强封装

{1}、

{2}、 这两个都是写在配置内里面的
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Bean
public Docket docket() {
log.info("准备生成接口文档");
ApiInfo apiInfo = new ApiInfoBuilder()
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.sky.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
//3、
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("开始生成静态资源映射");
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
{4}swagger 常用注解 用于解释说明用处的和swagger上面的显示 让swagger接口文档有更好的可读性

例:




二、CRUD
1、我们先把项目接口以json格式传到apifox里面 方便看文档写CRUD
以YApi的方式导入

登录后可以看到的

2、新增员工
{1} DTO为前端页面传过来的数据 而entity实体类里面的数据是完整的 DTO可能不完整(因为前端导入的数据不完整)
最后传到service层

{2} 首先传到service层 再到serviceImpl现实

这里由于EmployeeDTO是个不完整的数据, 现在Employee传入mapper层
所以现在需要把EmployeeDTO数据复制到Employee里面,以及把Employee里的属性值补齐
(1)MD5加密 DigestUtils.md5DigestAsHex
(2)LocalDateTime.now() 当前时间
(3)StatusConstant.ENABLE PasswordConstant.DEFAULT_PASSWORD 都为写好了的类,直接调用
(4)最后传给mapper

{3} mapper层
因为sql内容简单,这里直接使用注解完成

{4} 功能测试 这里我们使用到接口进行测试
(1)首先需要设置全局参数,因为jwt令牌会检验 如果不进行jwt检验 则会报401错误
参数名称:token yml文件配置的
参数值: 可以通过员工登录来获取token的值,来用于crud的jwt检验
参数类型: hearder



{5}完善代码 : username设置的是唯一的,当出现重复会报500
现将写入异常管理
MessageConstant.ACCOUNT_EXISTS_FOUND 为参数不存在
MessageConstant.UNKNOWN_ERROR为参数未知错误
String[] split1 = message.split(" ") 将空格做为分离 保存在数组中

{6} 完善代码2 将添加的 createUser updateUser动态的注入
这里就需要得到用户的id
这里我们就用到了 ThreadLocal
在jwt这里可以得到id

ThreadLocal的三大类 set get remove

JWT这里获取

最后动态注入

3、分页查询
{1} 首先查看api文档
请求参数:name page pageSize 对应我们的EmployeeLoginDTO 类
响应: data: 为 PageResult 类里面的属性值


{2} controller 现在我们已经知道了 请求参数和响应的数据内容
通过前端请求的EmployeeLoginDTO 来响应PageResult 调用service层

{3} service
1、这里通过插件 pagehelper进行分页查询
2、 employeeMapper.pagequery(employeePageQueryDTO)通过调用mapper执行sql语句来获取查询的数据
3、这里利用了插件 pagehelper 所有需要使用page来放回
3、 这里的page获取的查询的数据,通过page来得到PageResult里面属性的值


{4}mapper
1、这里通过执行sql语句来获取数据 ,放在page集合里面
2、concat是包含的意思

注意:这里 name !=''" 这里的单引号直接不能有空格且和双引号也不能有空格,否则到时候条件查询会报500

注意: 每个if中间都需要加一个and 即便最后一个if 也要加and 在if test里面判断的 name是实体类的属性不是数据库的,
只有在if中间判断的属性是数据库的(左边是数据库属性) = (右边是实体类的属性)
{5} 测试发现这里的时间格式不一致
1、直接在实体内加上@JsonFormat

2、统一放在配置类中

4、启动或禁用用户(这里需要id和status(状态))

{1} controller层

{2}service
注意:这里为了实现重复利用代码,这里可以直接修改employee用户的全部属性
而这里只需要修改里面的status,所以只把status传进去了

{3}mapper
这是修改employee里面所以属性的sql

5、修改员工信息

{1} 点击修改,将需要修改的信息回显到页面
通过查看api,页面传给id,查用户



{2}在回显的数据上修改
查看api 通过put请求来修改 ,而页面修改的属性对应 EmployeeDTO 这里必须加@RequestBody(返回Json格式),不然服务器接收不到

在service层中 可以重复利用上面修改的mapper方法 不过参数是Employee, 现在需要把EmployeeDTO copy到Employee
主要Employee里面的updateTime updateUser不能忘记

三、处理公共字段
这里利用的是aop机制
1、自定义注解

2、创建切面内容
{1}:@Pointcut切入点里面写着切入的范围
{2}:@Before通知 在@里面写入切入点对应的方法

3、在@Before对应的方法下:
{1}:获取注解@AutoFill里面的value的值
@AutoFill(value = OperationType.INSERT)
ProceedingJoinPoint 可以获取注解@AutoFill下所有的内容

{2}:这里的entity是为了获取下面的employee的值
准备赋值的数据

获取employee的参数(参考)

{3}: 最后判断赋值
getClass().getDeclaredMethod() 是通过反射来获取到类 getDeclaredMethod()里面name为赋值的对象name,后面为所赋值的类型
invoke()是通过反射赋值 invoke()里面一个是类(例:entity实体类) 第二个是赋值的值(例:now当前时间)

四、菜品类
一、新增菜品
1、文件上传
{1}这里是上传到阿里云 首先要导入阿里云的依赖包

{2}这里写好了AliOssUtil 的工具包
AliOssProperties为 阿里云所需要的属性值

在yml文件中写入 阿里云的值

{3}创建阿里云的配置类,将AliOssProperties的值导入AliOssUtil 工具中,且加入到ioc容器中

{4} 创建文件上传的controller
文件需要用 MultipartFile file 注意这里的file 是前面传递的,不能乱写
最后是调用了aliOssUtil 的方法upload
这里不需要调用service 已经mapper


2、新增菜品
首先查看api文档
前端导入的参数为 DishDTO中的属性
其中flavors为口味,是一个集合也在其中

{1} controller

{2} service
在serviceimpl层中 需要增加 菜品 和口味
在新增口味中,口味为可选,如果新增口味,前端只能新增其中的name和value 其中dishid没法前端增加
这里我们需要利用新增菜品insert后的 dish.getid得到dishId (通过在Dish.XML文件中)加入 useGeneratedKeys="true" keyProperty="id" 例 图3

图2

图3

{3}mapper
这里分别创建DishMapper(菜品) 和 DishFlavorMapper(口味)
DishMapper.xml

DishFlavorMapper.xml
注意service中传入的是集合,主键对应的values是多个,所以这里的values使用的是<foreach> </foreach>
collection为传入的对象 item自定义的对象 separator每个数组的分割

3、分页查询
首先看api
![]()
请求参数是Query 所以不用返回json格式
右图:这里响应的是DishVO 因为里面有categoryName 而不是Dish


{1}controller

{2}service
serviceImpl
注意:这里的DishVO没有对应的数据库类, 需要dish和category两个类结合起来才能得出DishVO里面的属性值

{3}mapper
这里我们使用了 join on 连接两个类 而不是用where连接 ,因为后面还需要使用<where>
如果这里的join on 写成where了,后面写<where>就重复了,直接报错

4、批量删除菜品
首先查看api 需要传入参数 ids 这里的id为多个

{1} controller
由于传入的id为多个,这里直接传入list集合 通过@RequestParam指定参数名称

{2} service
serviceImpl中
考虑:
一、当菜品为启用状态时,不能删除 这里通过mapper得到ids对应的菜品状态

对应的mapper

二、当菜品为套餐中的时候,不能删除 而 setmeal_dish为菜品和套餐的关系类 这里需要调用到setmealDishMapper来得到

对应的mapper 及sql

这里是多对多,通过list集合的dishId 来得到 list集合的SetmealId
下面的sql语句是通过: select setmeal_id from setmeal_dish where dish_id in (1,2,3,4....) 所编写 in后面的为list集合

三、删除菜品表中的菜品数据
四、删除菜品表中对应的口味数据 通过dish_id(ids) 得到dish_flavor类

三,四 对应的mapper


5、修改菜品
首先看api
思路:
{1}点击修改,需要回显数据
菜品分类和菜品图片已经写过,根据发现, 现在只需要根据id 得到dish和Flavor ,再存入dishVO,最后回显dishVO里面属性的数据
{2}回显数据后,需要将前端写好的dishVO数据保存(里面包括dish表 和口味表DishFlavor)
dishVO里面包括dish和DishFlavor
所以在serviceImpl中需要将 dishVO复制到dish, 再到数据库中执行sql, 口味表DishFlavor:先将回显的口味表删除,再添加前端导入的口味表

1、首先根据id ,回显数据 这里就是回显DishVO类
controller

serviceImpl
根据id 得出Dish 和 DishFlavor 最后放入DishVO类中

mapper 分别为


2、回显数据后,需要将前端写好的dishVO数据保存
controller

serviceImpl

普通数据的mapper里面的sql为( dishMapper.updateDish(dish); 通过动态sql进行修改操作

先删除原有的口味DishFlavor再插入前端传入的口味DishFlavor

这里的跟上面新增菜品里面的 新增口味DishFlavor一样 values为集合 用 foreach

浙公网安备 33010602011771号