瑞吉外卖
一、数据库搭建
建数据库-->建表
二、员工管理
1、登录功能实现
controller(接收用户输入的信息)-->传给service(通过mapper查询数据库实现对应的业务逻辑)-->mapper-->DB
1、创建实体类Employeee,和employee表进行映射
2、创建controller、service、mapper
3、导入返回结果类R
此类是一个通用结果类,服务端响应的所有结果最终都会包装成此种类型返回给前端页面。(也就是说在controller层接收到用户输入的信息后,无论正确与否,都要给用户返回一个提示信息,是否操作成功/失败,那么这个类就集成各种可能操作的信息,供返回给用户)
业务逻辑:
-
根据页面提交的密码password进行MD5加密处理,此时密码已封装在employee中。
-
根据页面提交的用户名username查询数据库。
-
如果没有查询到则返回登录失败结果。
-
密码比对,如果不一致则返回登录失败结果
-
查看员工状态,如果已为禁用状态,则返回员工已禁用结果
-
登录成功,将员工id 存入session并返回登录成功结果,用HttpServletRequest实现。
2、退出功能实现
员工登录成功后,页面跳转到后台系统首页面,此时会显示当前登录用户的姓名,如果员工需要退出系统,直接点击右侧的退出按钮即可退出系统,退出系统后页面应跳转回登录界面。
用户点击页面中退出按钮,发送请求,由请求地址判断为get/post请求我们只需在Controller中创建对应的处理方法来处理用户发送来的数据。
业务逻辑:
- 清理Session中的用户id
- 返回结果
3、员工管理业务
只有用户登录成功后,才能登录系统。
使用过滤器或者拦截器,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面。
业务逻辑:
- 创建自定义过滤器LoginCheckFilter
- 在启动类上加入注解@ServletCompentScan扫描过滤器
- 完善过滤器的处理逻辑
过滤器的处理逻辑:
1、获取本次请求的url
2、判断本次请求是否需要处理
3、如果不需要,则直接放行
4、判断登录状态,如果已登录,则直接放行
5、如果未登录则返回未登录结果
4、新增员工
后台系统可以管理员工,点击新增,即可添加员工信息。
执行流程:
- 页面发送Ajax请求,将新增员工页面中输入的数据以json的形式提交到服务器。
- 服务器controller接收页面提交的数据并调用service将数据进行保存。
- service调用mapper操作数据库,保存数据。
全局异常处理器
5、员工信息分页查询
执行流程:
- 页面发送Ajax请求,将分页查询参数(page、pageSize、name)提交到服务器。
- 服务器controller接收页面提交的数据并调用service查询数据。
- service调用mapper操作数据库,查询分页数据。
- controller将查询到的分页数据响应给页面。
- 页面接收到分页数据并通过ElementUI的table组件展示到页面上。
6、启用\禁用员工账号
在员工管理列表页面,可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统,启用后的员工可以正常登录。
需要注意:只要管理员(admin用户)可以对其他普通用户进行启用,所以普通用户登录系统后启用、禁用按钮不显示。
- 页面发送Ajax请求,将分页查询参数(id、status)提交到服务器。
- 服务器controller接收页面提交的数据并调用service查询数据。
- service调用mapper操作数据库,查询分页数据。
启用、禁用员工账号,本质上就是一个更新操作,也就是对status状态字段进行操作,在Controller中创建update方法,此方法是一个通用的修改员工信息的方法。
具体实现步骤:
- 提供对象转换器JacksonOjectMapper,基于Jackson进行java对象到json数据的转换。
- 在WebMvcConfig配置类中扩展Springmvc的消息转换器,在此消息转换器中使用提供的对象转换器进行java对象到json数据的转换。
问题:js对long型数据进行处理时丢失精度,导致提交的id和数据库中的id不一致。
解决:子服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串。
7、编辑员工信息
- 点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员工id]
- 在add.html页面获取url中的参数[员工id]
- 发送Ajax请求,请求服务端,同时提交员工id参数
- 服务端接收请求,根据员工id查询员工信息,将员工信息以json形式响应给页面
- 页面接收服务器端响应的json数据,通过vue的数据绑定进行员工信息回显
- 点击保存按钮,发送ajxa请求,将页面中的员工信息以json方式提交给服务器
- 服务端接收员工信息,并进行处理,完成后给页面响应
- 页面接收到服务端响应信息后进行相应处理
三、分类管理
1、公共字段自动填充(技术点)
对这些公共字段在某个地方进行统一处理。
也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。
实现步骤:
- 在实体类的属性上加入@TableField注解,指定自动填充的策略。
- 按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口
改造成动态获取当前登录用户的id
实现步骤:
- 编写BaseContext工具类,基于ThreadLocal封装的工具类
- 在LoginCheckFilter的doFilter方法中调用BaseContext来设置当前登录用户的id
- 在MyMetaObjectHandler的方法中调用BaseContext获取登录用户的id。
2、新增分类业务
流程:
- 页面(backend/page/category/list.html)发送Ajax请求。将新增分类窗口输入的数据以json形式提交到服务端
- 服务端Controller接收页面提交的数据并调用Service将数据进行保存
- Service调用Mapper操作数据库,保存数据。
3、分类信息分页查询
流程:
- 页面发送Ajax请求,将分页查询参数(page、pageSize)提交到服务器
- 服务器端Controller接收页面请求数据并调用Service查询数据
- Service调用Mapper操作数据库,查询分页数据
- Controller将查询到的分页数据响应给页面
- 页面接收到分页数据并通过ElementUI的Table展示到页面上
4、删除分类
流程:
- 页面发送Ajax请求,将参数id提交到服务器
- 服务端Controller接收页面提交的数据并调用Service删除数据
- Service调用Mapper操作数据库
如果要删除的id关联了菜品或套餐,则不许删除,所以我们需要进行功能完善。
5、修改分类
四、菜品管理
1、文件上传与下载
服务端要接收客户端页面上传的文件,通常都会使用Apache的两个组件。
- commons-fileupload
- commons-io
Spring框架在spring-web包中对文件上传进行了封装,大大简化了服务端代码,我们只需要在Controller的方法中声明一个MultipartFile类型的参数即可接收上传的文件。
2、新增菜品
流程:
- 页面发送Ajax请求,请求服务器端获取菜品分类数据并展示到下拉框中
- 页面发送请求进行图片上传,请求服务端将图片保存到服务器
- 页面发送请求进行图片下载,将上传的图片进行回显
- 点击保存按钮,发送Ajax请求,将菜品相关数据以json形式提交到服务端。
3、分页查询
- 页面(backend/page/food/list.html)发送Ajax请求,将分页查询参数(page、pageSize、name)提交到服务器,获取分页数据
- 页面发送请求,请求服务端进行图片下载,用于页面展示。
4、修改菜品
流程:
- 页面发送Ajax请求,请求服务端获取分类数据,用于菜品分类下拉框中数据显示
- 页面发送Ajax请求,请求服务端,根据id查询当前菜品信息,用于菜品信息回显
- 页面发送请求,请求服务端进行图片下载,用于图片回显
- 点击保存按钮页面发送Ajax请求,将修改后的菜品相关数据以json形式提交到服务器
五、套餐管理
1、新增套餐
其实就是将新增页面录入的套餐信息插入到setmeal表,还需要向setmeal_dish表插入套餐和菜品关联数据。
流程:
- 页面(backend/page/combo/add.html)发送Ajax请求,请求服务端获取套餐分类数据并展示到下拉框中
- 页面发送Ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中
- 页面发送Ajax请求,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
- 页面发送请求进行图片上传,请求服务端将图片保存到服务器
- 页面发送请求进行图片下载,将上传的图片进行回显
- 点击保存按钮,发送Ajax请求,将套餐相关数据以json数据形式提交到服务器。
2、套餐信息分页查询
流程:
- 页面(backend/page/combo/list.html)发送Ajax请求,将分页查询参数(page、pageSize、name)提交到服务端,获取分页数据
- 页面发送请求,请求服务端进行图片下载,用于页面图片展示
3、删除套餐
流程:
- 删除单个套餐,页面发送Ajax请求,根据套餐id,进行删除
- 删除多个套餐时,页面发送Ajax请求,根据提交的多个套餐id删除对应套餐
六、手机验证码登录(跳)
1、短信发送
(1)介绍:
常用的阿里云、华为云、腾讯云....
这里使用阿里云
应用场景:验证码、短信通知、推广短信
(2)注册账号
七、菜品展示、购物车、下单
1、导入用户地址簿
地址簿:指的是移动端消费者用户的地址信息,用户登录成功后可以维护自己的地址信息,同一个用户可以有多个地址信息,但是只能有一个默认地址。
2、菜品展示
流程:
- 页面(front/index.html)发送Ajax请求,获取分类数据(菜品分类和套餐分类)
- 页面发送Ajax请求、获取第一个分类下的菜品或者套餐
菜品展示功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。
3、购物车
在购物车中可以修改菜品和套餐的数量,也可以清空购物车。
- 点击对应的按钮,页面发送Ajax请求,请求服务端,将菜品或者套餐添加到购物车
- 点击购物车图标,页面发送Ajax请求,请求服务端查询购物车中的菜品和套餐
- 点击清空购物车,页面发送Ajax请求,请求服务端来执行清空购物车操作
八、用户下单
点击购物车的去结算按钮,页面跳转到订单确认页面,点击去支付按钮完成下单操作。
- 在购物车中点击去结算按钮,页面跳转到订单确认页面
- 在订单确认页面,发送Ajax请求,请求服务端获取用户登录当前的默认地址
- 在订单确认页面,发送Ajax请求,请求服务端获取当前登录用户的购物车数据
- 在订单确认界面,点击去支付按钮,发送Ajax请求,请求服务端完成下单操作
九、Git
1、概述
Git仓库:
本地仓库:开发人员自己电脑上的Git仓库
远程仓库:远程服务器上的仓库
commit:提交、将本地文件和版本信息保存到本地仓库
push:推送、将本地仓库和版本信息传到远程仓库
pull:拉取,将远程仓库问价和版本信息下载到本地仓库
Git GUI Here :打开Git图形界面
Git Bash Here: 打开Git命令
2、代码托管服务
GitHub、gitee....
- 注册码云账号
- 登录码云
- 创建远程仓库
- 邀请其他用户称为仓库成员
3、Git常用命令
(1)Git全局设置
- 设置用户信息
git config --global user.name "youyisi"
- 设置邮件
$ git config --global user.email "[email protected]"
- 查看配置信息
$ git config --list
(2)获取Git仓库
- 在本地初始化一个
git --init
- 从远程仓库克隆(常用)(要输入用户名、密码老是错)
git --clone
(3)工作区、暂存区、版本库概念
(4)Git工作区文件的状态
(5)本地仓库操作
(6)远程仓库操作
(7)分支操作
(8)分支合并,解决冲突
(9)标签操作
是指某个分支某个特定时间点的状态,通过标签,可以很方便的切换到标记的状态。比较有代表性的是人们会使用这个功能来标记发布结点。
十、IDEA使用Git
1、本地仓库操作
(1)本地初始化一个仓库/从远程仓库克隆
2、远程仓库操作
3、分支操作
十一、Linux
1、Linux简介
安全、稳定、免费、占有率高
(Linux)嵌入式系统:机顶盒、路由器....
通过SSH连接工具就可以实现从本地连接到远程的Linux服务器。
SSH:建立在应用层基础上上的安全协议。
2、常用命令
3、文件目录类
(1)ls
(cd)
(cat)
(more)
(tail)
(mkdir)
(rmdir)
(rm)
4、文件拷贝
(cp)
(mv)
(tar)
5、文本编辑类
三种模式命令
6、查找命令
7、软件安装
(1)安装jdk
(2)安装Tomcat
防火墙操作:
(3)安装mysql
(4)安装Irzsz
8、项目部署
(1)手工部署项目
找进程对应的ID号
(2)通过shell脚本自动部署项目
十二、Redis基础
1、简介
是一个基于内存的key-value结构数据库(看官网)
是一种结构化的noSql数据库
nosql:(not only sql)非关系型数据库,它是对关系型数据库的补充。
- 基于内存存储,读写性能高
- 适合存储热点数据(热点商品、资讯、新闻)
- 企业应用广泛
2、入门
3、应用场景
- 缓存
- 任务队列
- 消息队列
- 分布式锁
4、数据类型
key-value:key是字符串类型
value有:
- 字符串String
- hash适合存储对象
- list列表按照插入顺序排序,可以有重复元素(可以实现任务队列)
- set无序集合,没有重复元素
- sorted set有序集合,没有重复元素
5、常用命令
(1)String
(2)Hash
(3)list
(4)无序集合set
(5)有序集合sorted set
(5)通用命令
6、java操作redis
1、介绍
2、jedis
3、Spring Data Redis
十三、项目优化
1、缓存优化
如果移动端的用户较多,会对数据库造成的压力较大,系统性能下降,用户体验差。
使用缓存来解决,先查缓存,缓存没有的话,再查数据库。
(1)环境搭建
- maven坐标
- 配置文件
- 配置类
(2)缓存短信验证码
- 在服务端UserController中注入RedisTemplate对象,用于操作Redis
- 在服务端UserController中sendMsg方法中,将随机生成的验证码缓存到redis中,并设置有效期为5分钟
- 在服务端UserController的login方法中,从redis中获取缓存的验证码,如果登录成功则删除redis中的验证码
(3)缓存菜品数据
在高并发的情况下,频繁查询数据库会导致系统性能下降,服务端响应时间增长,现需要对此方法进行缓存优化,提高系统的性能
- 改造DishController的list方法,先从redis中获取菜品数据,如果有则直接返回,无需查询数据库,如果没有则查询数据库并将查询的菜品数据放入到redis中
- 改造DishController的save和update方法,加入清理缓存的逻辑
注意:保证数据库中的数据和缓存中的数据一致,如果数据库中的数据发生变化需要及时清理缓存数据。
(4)Spring Cache
是一个框架,实现了基于注解的缓存功能。
提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。
CacheManager是Spring提供的各种缓存技术的抽象接口。
针对不同的缓存技术需要实现不同的CacheManager
(5)缓存套餐数据
- 导入Spring Cache和Redis相关的maven坐标
- 在application.yml中配置数据的过期时间
- 在启动类上加入@EnableCacheing注解,开启缓存功能
- 在SetmealController的list方法上加入@Cacheable注解
- 在SetmealController的save和delete方法上加入CacheEvict注解
十四、读写分离
读和写所有压力都由一台数据库承担,压力大数据库服务器磁盘损坏,单点压力大。
写操作(Master主库)、读操作(Slave从库)
Mysql主从复制:把主库的数据同步到从库,实现数据同步。
1、Mysql主从复制
(1)介绍
(2)配置
(3)测试
2、读写分离案例
使用Sharding-jdbc可以在程序中轻松的实现数据库读写分离。
Sharding-jdbc是jdbc的加强版
3、项目实现读写分离
十五、Nginx基础
1、概述
下载与安装
2、常用命令
-
./nginx -v 查看版本号
-
./nginx -t 在启动nginx服务之前,可以先检查一下conf/nginx.conf文件配置的是否有错误
-
.nginx 启动服务
-
nginx -s stop 停止服务
-
./nginx -s reload 修改配置文件后,重新加载配置文件
3、配置文件结构
(1)全局块
(2)events块
(3)http块
4、具体应用
(1)部署静态资源
(2)反向代理
(3)负载均衡
十六、前后端分离开发
不分离时:
- 分工不明确
- 开发效率低
- 不便于管理
- 对开发人员要求高
1、前后端分离开发
2、Yapi
提供更优雅的接口管理服务。