# 校园购 **Repository Path**: xedesss/NcuLikes ## Basic Information - **Project Name**: 校园购 - **Description**: 一个基于苍穹外卖进行的小小项目练习,补充了许多东西 包含springBoot,springMvc,Mybatis,Mysql,jwt,Swagger,Maven,git,lombok,Vue,apiFox等等技术 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2024-11-01 - **Last Updated**: 2025-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: Java, SpringBoot, MySQL, MyBatis, Spring-MVC ## README # skyTakeOut_byXie ### 介绍 一个基于[苍穹外卖](https://www.bilibili.com/video/BV1TP411v7v6)进行的小小项目练习 包含springBoot,springMvc,Mybatis,Mysql,jwt,Swagger,Maven,git,lombok,Vue,apiFox等等技术 贴几篇关于这个项目讲的很好的博文:[比较Redis和SpringCache](https://blog.csdn.net/m0_37501154/article/details/89491577),[一字一句,带你读懂“外卖项目”](https://www.nowcoder.com/discuss/689909457387540480) ### 如果你想部署下来 用依赖文件夹的文件建好sql表,打开本地Redis服务器,在无中文目录下打开Nginx服务,在/src/main/resourse中配置好.yml文件:阿里云的key,WeChat的key,本地数据库的密码即可。 ### 开发笔记 #### Day1 对应教程p12-p30的内容 实现了新增员工,员工分页查询,启用禁用员工账号,编辑员工功能,并导入了分类管理相关的已打包好的代码。 1. Swgger小工具实现了方便的前后端联调。只需在开发的接口上使用注解@Api****,通过设置静态资源映射将要开发的接口汇总到html页面上,还能对接口进行测试 2. Mybatis可以便捷地将数据写入持久层。值得注意的是由于sql语句是直接拼接的,编译器不会提醒,一定要避免列名拼写错误。 关于[配置idea的MySQL语言提示](https://blog.csdn.net/qq2523208472/article/details/89366264) 3. 数据传输过程中一定要注意信息安全。在此项目中的对象传递皆进行了加密,密码使用MD5加密存储,在返回给前端实体对象时对密码进行消除处理。 4. jwt令牌是很有意思的东西,实现了对登录状态的保存。通过每次请求带上后端返回的header,通过解析jwt令牌可得出当前登录的用户id。 [jwt令牌详解](https://www.bilibili.com/video/BV1m84y1w7Tb/?vd_source=5f16547dd75b4f99740f721e734a6cfe&p=161) 5. 实际开发中的代码风格,项目组织是与学院派大相径庭的。包括通过实现@Builder的链式编程风格,web中的[RESTful风格](https://www.bilibili.com/video/BV1Fi4y1S7ix?vd_source=5f16547dd75b4f99740f721e734a6cfe&p=54),控制层controller,持久层mapper,业务层service的MVC三层架构风格都让我受益匪浅 6. common中的BaseContext类通过ThreadLocal实现了对象在不同层的传递,因为每一个请求都要经过jwt令牌,于是在此处将id传入BaseContext,从此这个线程就会一直携带此信息 7. 复习了Markdown的[编写语法](https://zhuanlan.zhihu.com/p/108984311) #### Day2&Day3 对应教程p31-p62的内容 实现了新增菜品,菜品分页查询,删除菜品,编辑菜品等功能,并初步了解了Redis在Java环境下的使用。 1. 和操作员工对象最大的不同是,菜品关联了菜品口味,对每一个对象的操作实际上是在操作两张表,由此引申出数据的一致性问题。于是进行数据库读写的方法都使用了Spring事务,实际使用非常方便加上@Transactional即可。 2. 项目所含对象属性有一定重合度,这里将面向[切面编程思想AOP](https://www.bilibili.com/video/BV1m84y1w7Tb?vd_source=5f16547dd75b4f99740f721e734a6cfe&p=175)利用上了。实现了一个注解@AutoFill,可将对象的updatexxxx属性一并更改,简化了代码。值得注意的是,写入数据库时仍需要进行对应的插入。 3. 修改对象时后端需要将数据返回前端,然后前端再做操作,教程的对象封装非常有序,返回前端的对象一律为xxxxVO,前端返回的一律为xxxxDTO,存入数据库的对象为xxxx。 4. 菜品是包含图片信息的,实际项目肯定不能使用本地的静态资源,而是需要使用云服务来传递图片,由此引入阿里云OSS服务,并学习了[相关的api以及环境配置](https://www.bilibili.com/video/BV1m84y1w7Tb?vd_source=5f16547dd75b4f99740f721e734a6cfe&p=148) 5. p50-p62为Redis补充教程,不对项目进行实际编写。 6. 从这里关于项目中两个最主要的对象:员工和菜品的相关代码编写已完成,越往后就越熟练。从最开始的报错之后一头雾水,然后慢慢学习对Spring框架下项目的Debug,最后能做到对返回的错误码有一定了解,对错误快速定位并修改。从最开始对接口编写无从下手,现在已经形成controller-->service-->mapper-->数据库的流程化编码。同时对项目最开始的对象为何要如此创建有了更深的理解。 #### Day4&Day5 对应教程p63-p85的内容 补全了套餐相关的CRUD接口,实现了微信端小程序的登录功能(其实就是用户端登录),导入了后端商品浏览相关的代码,前端微信小程序的代码 1. 用HttpClient类引入网络编程,可以在对应的URL上获取到返回的数据,真是十分神奇。数据传输的方式也区分GET,PUT等,和web有共同之处。 2. 从0开始了解微信小程序的编写。引入了“微信开发者工具”这个国产编译器,实际界面以及内容就是前端代码,和Vue很相似。但接触一个新的编译器还是有点痛苦的。 3. 套餐类是菜品以及菜品口味的综合类,和前面的代码有一点区别,比如套餐设置要检查每一样菜品的状态,但大部分是非常相似的。 4. 学会了一个重要的idea快捷键:Ctrl+Alt+M提取方法。可以显著提升效率。 #### Day6 对应教程p86-p97的内容 实现了利用Redis对对象的缓存,粗略了解SpringCache缓存注解开发。 1. 用Redis缓存了查询的菜品对象已经清除缓存,减轻了数据库的查询压力并保证数据一致性。这里的缓存功能有点多此一举,因为在修改菜品时就要清除全部缓存。 2. 发现了一个小bug,因为状态设置是在访问/admin/shop/{status}时缓存到Redis的,如果只开启服务器和用户端,是无法得到正常状态的,可能是默认管理端会打开。 3. SpringCache实质上是Spring框架对Redis等数据库的实现,是为了简化开发而生的。它使用spEL语言。用它的注解对setMeal的控制层进行了改造。 #### Day7 对应教程p98-p109的内容 实现了用户端购物车添加,减少,清空,并引入了地址簿模块代码 1. 在编写过程中越发觉得项目设计还有许多不合理之处。为了实现套餐的CRUD,菜品口味的CRUD要编写很多额外的代码,不仅降低了可读性,还增加了开发难度。我觉得前期设计就应该把套餐当做普通菜品类,口味等次级数据统一归入备注属性中,这样在工程上实现了相同的功能也能简化开发。 2. 购物车的CRUD和前面的内容还是很相似。每次操作要先查询数据库然后再进行修改,直接用前端的数据又不安全,有没有更好的办法呢 3. 发现了自己写的一个小bug。在数据库微信登录的user表中发现了大量相同openid的数据,实际上每次登录都插入了新user,发现检查老用户的select语句错误的将id与openid来比对检查。 #### Day8 对应p110-p145的内容 完善了用户下单,催单,订单状态刷新功能,对接了微信支付接口,实现了一部分数据统计,粗略了解SpringTask框架,WebSocket技术,还有基于JS的前端Apache EChart可视化图表库 1. 在配置SpringTask的参数cron表达式时非常麻烦,这里有一个[cron生成网站](https://cron.qqe2.com/)。需要时直接生成即可。 2. WebSocket区别于Http协议,是基于TCP的网络协议,实现了浏览器与服务器[全双工通信](https://upimg.baike.so.com/doc/426296-451472.html)。服务器可以主动向用户发起通信,例如视频弹幕,网页聊天等等。 3. 微信支付没有企业的私钥,调用不了付款接口。设计填充了一个虚拟JSON对象进入方法,跳过了验证并成功运行。 4. 查询营业额是和前面的内容不太一样的。操作LocalDate,LocalDateTime等jdk包含的原生类很多。顾名思义,后者多了time。加深了对原生api的理解。 5. 粗略感觉Apache EChart是一个不错的框架,能将JSON数据变成好看的图表,这样的框架好像还挺多。 #### Day9 对应p146-p165的内容 实现工作台信息界面,补全了数据统计和订单状态,现可设置订单的接单,拒单,派送等状态了。了解了Apache POI这种处理Excel格式的开源项目。 1. 导出Excel表的内容就先不写了,在实际后端开发中用处一般吧。 2. 因为前面编写的Mapper已经很成熟,越往后越轻松,工作台只需调用对象各自的Mapper然后封装VO即可。果然是万事开头难,项目刚开始所有的接口都不能用还是挺麻烦的。 3. 到这里项目应该已经完成了,后面粗略看了一下补全前端框架搭建以及编写。Vue的内容在JavaWeb课程中有所涉及,这里先不复习了。 #### DayN 写完这些还是有一些自己的想法的,可以为以后的优化先画一个饼。 1. 众所周知Redis的缓存穿透,击穿,雪崩是比较常见的问题,该项目完全没有考虑,对DB的性能很是相信,可以考虑优化。 ### 后记 在开始写这个东西前已经慢慢积累了许久,从大一看的[Java基础](https://www.bilibili.com/video/BV1fh411y7R8/) 然后[JavaWeb技术](https://www.bilibili.com/video/BV1m84y1w7Tb/),感觉两者跨度有点大,又补完了[SSM框架](https://www.bilibili.com/video/BV1Fi4y1S7ix/), 包括看的[Git教程](https://www.bilibili.com/video/BV1MU4y1Y7h5/),[网页如何显示](https://www.bilibili.com/video/BV1Tx421m7Hv),这些边边角角的内容也是学习了。 终于终于,将自己的学习外化出了一个小结果出来。虽然很多更深的,底层的东西还不甚了解,再说吧。下面是自己在编写过程中的疑惑和心得体会 #### 注解开发 Spring项目优势可以是注解开发,通过使用自定义注解类和框架包含的注解可以大大简化开发,增加代码可读性。@Data是lombok下的注释,可将对象的构造方法,getter,setter一键生成,而@Slf4j可使用log.info在控制台打印日志。 @Api@ApiOperation是Swagger下的注释,可以生成方便后端开发的静态接口文档。@Select@Update@Mapper等是Mybatis下的注释,可以通过他们对JDBC直接操作,非常方便。 @Aspect@PointCut@Before等等是用于标记和操作AOP的注释,在项目的AutoFillAspect类中使用,定义了自定义注解@AutoFill。 @DateTimeFormat@PathVariable@RequestBody等对是对参数进行操作。MVC包含的@**Mapping用于响应前端的访问,最基础的@Bean@Service@RestController@Autowired都是Spring操作bean的。 #### 微信客户端管理端区别 项目只写了微信客户端和网页管理端,它们都是前端工程,区别应该在于两者页面差别巨大,对后端访问的权限也有差别。 #### 数据库设计重要性 该项目有大量查表,插入,更新语句,联表查询还是非常复杂且容易出错的。而且表还不算很多,也没有非常繁琐的SQL语句。如果前期不好好设计,对后面的开发绝对是上强度的。 #### 为什么数据库表和后端变量名之间隔着驼峰命名映射 其实是两种语言的传统决定的。MySQL语言不区分大小写,为了辨识只好使用“_”。而Java的传统就是使用驼峰命名。两边名字不统一确实会造成一下编写上的困难,但也是无奈之举。