苍穹外卖学习记录

166 阅读5分钟

技术选型

image.png

Nginx反向代理与负载均衡

image.png

image.png

image.png

负载均衡

image.png

image.png

反向代理

nginx.conf文件如下(实现跨域):

image.png

image.png

用户脱敏

为了用户隐私安全,数据库存储的登录密码一般不以明文存储,而是通过加密算法后再存储,一般加密算法用md5等,因此前端要想通过用户登录校验,就需要在后端用户登录方法中对输入的密码进行同样的算法加密,才能匹配上数据库的密码,从而正常登录

image.png

新增员工

DTO:当controller方法所需参数并不完整需要实体类所有参数时,可以封装一个请求体,只包含请求所需要的参数,这个请求体就叫DTO,采用DTO可以使前端人员在进行postman调试时更加清楚哪些参数是必要的,方便开发

比如用户登录,只需要id、username、name、phone、sex、idNumber等参数,不需要其他参数了(员工实体类包含有其他参数)

image.png

controller层:调用持久层方法

image.png

service实现类(持久层)实现方法:由于请求体DTO只传递必要的参数,而向数据库新增用户肯定是包含一些其他字段的,所以需要把DTO转换为对应的实体类,使用拷贝方法copyProperties,这样没传的参数在实体类对象中被设置为null

注意这里使用MP更好

image.png

TODO:接口文档发送请求携带token,否则无法通过jwt令牌校验,前端人员无法测试发送请求,token也可能会过期

全局异常处理器

这里不是采取后端代码对用户名进行校验,而是在用户名重复的时候对异常进行拦截处理

正常来说,应该在编写代码的时候就考虑的用户名重复的情况,并在后端对其做校验

像"已存在"这类字符串最好封装成常量类的某个常量

image.png

动态获取id

上面在新增用户的时候,用户id采用固定的10L,现在要修改成每个用户有各自的id

首先是jwt令牌认证,过程如下,生成的jwt token时将用户id放进去了

image.png

具体流程

TODO 为什么是先登录获取用户id,再新增用户?

用户登陆成功生成jwt token

image.png

用户生成jwt token之后的每次登录都会在请求头requestHeader中携带该token,通过token拦截器可以获取该token,并进行校验,从而再次登录

image.png

从token中获取到用户id,然后将该用户id(当前登录用户),传到新增用户的setCreateUser、setUpdateUser中,由于每次请求(调用一个controller方法)是一个线程,只有在线程内才能获取到对应的值(新增用户是一个请求,用户登录是一个请求,所以新增用户与用户登录是两个线程,用户登录token中获取到的用户id不能传给新增用户所需要的setCreateUser、setUpdateUser),所以需要一个全局存储器来存储这个用户id,实现跨线程使用

TODO 既然使用ThreadLocal来存储并共享使用变量,为什么还说成是具有线程隔离效果?不应该是解决线程隔离问题吗?

image.png

全局存储器

image.png

存储变量

image.png

获取变量

image.png

用户分页查询

封装请求体DTO

image.png

封装通用返回结果

image.png

封装分页查询结果

image.png

image.png

封装前端返回结果

实际上我觉得这里使用VO更好 image.png

具体实现

controller层

image.png

service层

image.png

service实现类

image.png

视频里采用pageHelper来分页(不用mp就老是要去mapper里写对应的sql语句),我更倾向于使用mp的querywrapper来分页 image.png

分页查询结果日期格式化

数据库里存储时间的数据类型是列表,渲染到前端就是一整串数字而不是常见的时间格式,所以需要格式化

image.png

image.png

image.png

启用禁用员工账号

controller层 通过url传参,使用@PathVariable注解,如果参数名一致则不需要额外指明从url中取哪个参数

image.png

service层

image.png

service实现类 没必要用构建器(@Builder注解),正常的new对象就可以了

image.png

编辑员工

根据id查询员工

controller

image.png

service

image.png

service实现类:这里将密码手动设置成隐藏的形式,最好是使用VO将结果返回给前端

image.png

修改员工数据

controller

image.png

service

image.png

service实现类:我不支持这种做法,因为如果原先数据库中员工所有字段都是有值的,如果只拷贝请求体的参数,那些本来有值的字段就变成null了,丢失数据,最好避免这种做法,还是手动改比较好(用MP更轻松)TODO

image.png

公共字段自动填充

存在的问题

image.png

实现方法

编写完后记得删除原来的手动设置

image.png

封装枚举类

image.png

自定义注解

image.png

定义切面类

切入点@PointCut注解定义了要拦截的方法所在的位置 和 所使用的注解 使用前置通知,实现在数据库更新操作之前拦截方法,JoinPoint可以获取到拦截到的方法、注解、参数等

image.png

image.png

image.png

image.png

image.png

拦截加了注解的方法

image.png