《苍穹外卖》学习笔记

67 阅读15分钟

1.前端依靠Nginx

Nginx(发音为 “engine-x”)是一个高性能的 ​​开源 Web 服务器软件​​,同时也是一个 ​​反向代理服务器、负载均衡器 和 HTTP 缓存​​ 工具。 可以把 Nginx 想象成一个 ​​“网络交通警察” 或 “接待员”​​,它的主要工作是:

  • ​接收用户(浏览器)发来的请求​
  • ​根据配置决定如何处理这些请求​
  • ​把请求转发给合适的服务(如后端应用、静态文件等)​
  • ​并将结果返回给用户​

2.后端基于maven进行项目构建

Maven​​ 是一个 ​​Java 项目管理和构建自动化工具。​​它主要用于帮助 Java 开发者更高效地 ​​管理项目的依赖(第三方库)、构建项目(编译、测试、打包)、生成文档以及进行项目生命周期管理​​。

如果你刚刚接触 Maven,推荐这样做:
  1. ​学会写一个最基本的 pom.xml,引入一个依赖(比如 junit)​
  2. ​掌握几个常用命令:mvn compile、mvn test、mvn package​
  3. ​了解项目结构,知道代码该放哪里​
  4. ​学会在 IDE(如 IntelliJ IDEA)中使用 Maven​
  5. ​逐步尝试多模块项目、打包部署、与 Spring Boot 结合使用​

maven也是需要自己去下载的

3.后端环境搭建——Git

使用Git进行版本控制,具体操作:

  • ​​创建Git本地仓库
  • ​​创建Git远程仓库
  • ​​将本地文件推送到Git远程仓库

Git 的核心作用(通俗理解)

可以把 Git 想象成一个 ​​“时光机 + 协作本”​​,它的用途主要包括:

用途说明类比
​记录代码的变化历史​每次你修改了代码并提交,Git 都会记录下来:改了什么、什么时候改的、谁改的像日记本,记录每次改动
​回退到之前的版本​如果新代码出 bug 了,可以轻松回到之前正常的版本像时光倒流,一键回到昨天
​分支开发​可以开多个“分支”来同时开发不同功能,互不干扰像平行宇宙,不同功能分开做
​多人协作​多个开发者可以一起开发同一个项目,互不冲突像多人编辑同一本书,但有版本管理
​代码备份与共享​代码可以存储在远程仓库(如 GitHub、GitLab、Gitee),方便备份和团队共享像网盘 + 协作平台
​代码审查与集成​可以对代码变更进行审核、合并,保证质量

把Git搭建到IDEA上面历经步骤:

1.首先到官网下载Git
2.然后在IDEA里面创建本地仓库,具体过程与教程不同,要自己去摸索IDEA上面的功能,去找。
3.到gitee创建远程仓库。
4.然后将本地仓库与远程仓库关联。
里面涉及很多细节步骤,但是大方向还是很清晰明了的。

image.png

image.png

4.后端环境搭建-数据库环境搭建

先是下载数据库,然后还需要下载一个数据库可视化软件,将本地数据库与软件相连接。
在启动项目的时候,出现了一系列错误,考虑是IDEA版本不兼容导致的问题,需要从设置中调整IDEA版本

屏幕截图 2025-10-30 140222.png
在使用mad/命令提示符的时候,出现了“此时不应有 Files\Java\jdk-11==”问题,问题出自JAVA11环境变量配置。若地址中包含空格,则应加双引号括起来,但是我的没起反应,最终,得知了"program files"和"program files(x86)"可以用另一个没有空格的名称替代:PROGRA ~ 1和PROGRA ~ 2代替。然后问题就解决了,可以正常使用了。
从环境变量配置中我了解到,是在为程序运行时提供一些 ​​动态的、敏感的、环境相关的配置信息​​,比如数据库密码、API 密钥等,而不是把这些信息直接写死在代码里。
运行项目前,可以先Clean一下。

5.后端环境搭建-前后端联调-断点调试

通过断点调试,对登录代码进行逐行分析,但目前只了解了一点前端发送请求,后端传来数据,然后两者在代码中进行比对

6.Nginx反向代理和负载均衡

总结(简洁版)

概念说明作用
​Nginx 反向代理​用户访问 Nginx,Nginx 把请求转发给后面的应用服务器(如 Spring Boot)隐藏后端、统一入口、安全控制、请求转发
​Nginx 负载均衡​Nginx 将用户请求​​分发到多个后端服务器​​,让它们共同处理提升并发能力、高可用、容错、性能优化
​常见搭配​反向代理 + 负载均衡,是现代 Web 应用、微服务、高并发系统的基础设施Nginx 是实现这些功能的轻量、高效、稳定的工具

常用反向代理配置(Nginx配置文件中):

    listen 80;
    server_name example.com;

    location /api/ {
        proxy_pass http://localhost:8080/;  # 转发到后端服务
    }
}

常用负载均衡配置:

    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}
server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://backend_servers;  # 转发到上面定义的后端组
    }
}

7.md5加密处理

使用DigestUtils.md5DigestAsHex对前端传来的密码进行加密处理

改进了代码后,登录出现密码错误的报错,搞了好长时间,现对加密处理的过程进行阐述:
在登录页面输入明文密码,此明文密码在代码中被md5加密,然后与数据库中保存的加密密码进行比较。 注意:我的问题就出在把数据库中的加密密码录入错了,我是直接复制粘贴进去的,但是这样可能会让加密密码中出现一些看不见的特殊字符,最终导致密码不匹配。更加稳妥的方法是用代码Update修改保存的数据。
例如:

UPDATE sky_take_out.employee
SET password = 'e10adc3949ba59abbe56e057f20f883e'
WHERE username = 'admin';

8.接口

​API 接口(Application Programming Interface,应用程序接口)⭐ 最常见​

  • ​API 接口就是:服务端提供给客户端(比如前端、App、第三方)调用的一套“规则”或“入口”​​,让它们可以通过 ​​网络请求(如 HTTP 请求)​​ 来获取数据或执行操作。
  • 通常以 ​​URL(接口地址) + 请求方法(GET/POST等) + 参数 + 返回数据(如 JSON)​​ 的形式存在。

如果你刚刚开始学接口,建议了解以下内容:

  1. ​什么是 HTTP 请求(GET / POST / PUT / DELETE)​
  2. ​什么是 JSON 格式(接口常用的数据格式)​
  3. ​如何用 Postman 测试接口​
  4. ​如何用 Spring Boot 编写一个 RESTful 接口​
  5. ​什么是接口文档(如 Swagger / YApi)​
  6. ​什么是前后端分离,为什么需要接口​

9.@注解

总结

项目说明
什么是注解?一种元数据,用来为代码添加额外信息,不影响代码本身逻辑,但可被编译器、工具或运行时读取
注解有什么用?提供编译检查、生成代码、框架配置、代码提示、运行时动态行为等
常见例子@Override@Deprecated@Autowired@Test@RestController
如何自定义注解?使用 @interface关键字定义,并可配合元注解如 @Retention@Target使用

通过注解可以控制生成的接口文档,使接口文档具有更好的可读性。
Swagger常用注解:

image.png

10.功能开发一般步骤

1.需求分析和设计
2.代码开发
3.功能测试
4.代码完善

11.代码开发一般详细步骤(以一个例子为例)

1.先在Controller.java里面
2.然后去Service.java里面创建一个方法
3.然后在ServiceImpl.java里面: 这里面的代码好像是完成功能的代码主体(这个例子包含了四个具体功能)
4.然后在Mapper.java里面创建一个方法
5.然后又创建了一个Mapper.java
6.然后又创建了一个Mapper.xml

总结:每一层的作用一句话概括

名称作用一句话总结
Controller控制层 / Web 层接收 HTTP 请求,调用 Service,返回响应“谁来请求我,我该调用谁,返回什么”
Service业务逻辑层(接口)定义业务方法(做什么)“我要提供哪些服务(方法)”
ServiceImpl业务逻辑层实现实现业务逻辑,调用 Mapper“我具体怎么实现这些服务”
Mapper数据访问层(接口)定义数据库操作方法“我要怎么访问数据库(方法定义)”
Mapper.xmlSQL 映射文件编写真正的 SQL 语句“SQL 到底怎么写,怎么查/插/改/删”

整体逻辑:
前端给controller层发json,controller层把json封装为DTO发给Service,其实Service接口啥没有,只有一个调用方法,就完全控制着Impl。impl处理前端或后端传过来的数据。处理完具体业务,Service拿走处理完的成果交给controller层或者mapper层。mapper层包括mapper接口和mapper.xml。Mapper 接口定义 “要执行增删改查什么操作”,Mapper.xml 定义具体 执行的SQL。mapper层返回给Service层的是entity实体类。Service层处理完业务返回给controller层,controller层返回给前端有两种,一个是返回VO对象数据return Result.success(orderPaymentVO); 一种是直接返回return Result.success();

这五层分别的详细的介绍

Controller.java(控制层 / 表现层 / Web 层)
✅ 职责:
  • 接收前端(比如浏览器、APP、Postman等)发起的 HTTP 请求
  • 解析请求参数(如 URL 参数、表单、JSON 请求体等)
  • 调用 Service 层处理业务逻辑
  • 组织响应数据并返回给前端(如 JSON、HTML 等)
✅ 常见操作:
  • 使用注解如 @RestController@RequestMapping@GetMapping@PostMapping
  • 接收参数:@RequestParam@PathVariable@RequestBody
  • 返回结果:直接返回对象(Spring 会转为 JSON)、ResponseEntity

Service.java(业务逻辑层接口)

✅ 职责:
  • 定义业务逻辑操作的接口(抽象方法)
  • 是 Controller 调用的入口,但不包含具体实现
  • 通常只包含方法签名,起到接口规范和依赖注入的作用

ServiceImpl.java(业务逻辑层实现类)

✅ 职责:
  • 实现 Service 接口中定义的业务逻辑
  • 编排业务逻辑(可能涉及多个操作、判断、事务等)
  • 调用 Mapper(DAO)层,与数据库交互,获取或保存数据
  • 通常会使用 @Service注解,让 Spring 管理该 Bean

Mapper.java(数据访问层接口 / DAO 接口)

✅ 职责:
  • 定义与数据库交互的方法(如查询、插入、更新、删除)
  • 通常是一个 Java 接口, ​ 不包含具体实现
  • 与 MyBatis 的 Mapper.xml 文件一起使用,或者使用注解方式编写 SQL
  • 通过 @Mapper注解或在启动类上使用 @MapperScan让 MyBatis 扫描到该接口

Mapper.xml(MyBatis 的 SQL 映射文件)

✅ 职责:
  • 编写实际的 SQL 语句(如 SELECT、INSERT、UPDATE、DELETE)
  • 将 SQL 语句与 Mapper 接口中的方法进行映射
  • 定义如何将数据库查询结果映射为 Java 对象(如 resultType / resultMap)
  • 通常放在 resources/mapper/目录下,文件名与 Mapper 接口对应,如 UserMapper.xml

12.Redis简介

Redis是一个基于内存的key-value的结构数据库。
MySQL是写在磁盘上的数据库。
当数据访问次数频繁的时候,采用Redis存储,其余一般都用MySQL存储,因为Redis读写性能高。

常用命令

字符串操作命令:

image.png

Hash操作命令:

image.png

列表操作命令:

image.png

集合操作命令:

image.png

有序集合操作命令:

image.png

通用命令

image.png

13.HttpClient

HttpClient​ 是一个用于发送 HTTP 请求​ 和接收 HTTP 响应​ 的工具或库,通常用于客户端(如 Java 应用、C# 程序、Python 脚本等)与 Web 服务器​ 进行通信。它允许程序像浏览器一样向某个 URL 发送请求(比如 GET、POST),并获取返回的数据(如 HTML、JSON、XML 等)。
API附加说明:
在计算机和互联网世界中,API 是一组定义好的规则和协议,用来让不同的软件应用之间互相通信
在现代软件开发,尤其是 Web 和移动开发中,最常见的 API 是基于 HTTP 协议的 Web API,比如:

  • 你开发一个手机 App,需要显示天气信息,你不会自己去收集气象数据,而是调用某个气象网站提供的 API,传入城市名,它就会返回 JSON 格式的天气数据。
  • 你做一个网站,想让用户能用微信登录,你调用 微信开放平台提供的 API,按照它的要求传参数,它帮你完成登录验证。

🔹 这些 API 一般通过 URL(接口地址) ​ 访问,使用 GET、POST​ 等 HTTP 方法,并以 JSON / XML​ 格式返回数据。

14.微信小程序开发

小程序目录结构:
文件                    作用
app.js           小程序逻辑
app.json       小程序公共配置
app.wxss      小程序公共样式表

15.前后端联调时各类报错

401 Unauthorized(未授权)
  • 表现:前端请求返回401状态码,无法访问需要认证的接口

  • 原因

    • 用户未登录或Token过期
    • Token未正确携带在请求头中
    • 请求路径未被拦截器放行
404 Not Found(接口不存在)
  • 表现:前端请求返回404,后端显示"No mapping for GET/POST"

  • 原因

    • 后端Controller路径映射错误
    • 请求方法不匹配(GET/POST混淆)
    • 包扫描配置问题
500 Internal Server Error(服务器内部错误)
  • 表现:前端收到500错误,后端控制台有异常堆栈

  • 原因

    • 空指针异常(NPE)
    • 数据库操作异常
    • 业务逻辑错误
  • 解决方案

    • 查看后端日志定位具体错误行
    • 添加空值检查和数据验证

16.Spring Cache简介

Spring Cache​ 是 Spring 框架提供的一个缓存抽象层,它本身并不提供具体的缓存实现,而是在应用程序代码和多种缓存解决方案(如 Redis、Ehcache、Caffeine 等)之间建立一个统一的、一致的编程模型。你可以把它理解成一个  “缓存中间件” ​ 或  “缓存管理器”

image.png

17.DTO和VO的区别

基本概念对比

维度DTO (Data Transfer Object)VO (View Object)
目的数据传输,层间交互视图展示,前端渲染
使用场景Controller↔Service层Controller↔前端页面
数据内容与业务逻辑相关与页面展示相关
字段命名遵循Java规范可能遵循前端规范

DTO - 用于接收查询参数
VO - 用于返回给前端的数据

代码示例:
public Result register(@RequestBody UserRegisterDTO userRegisterDTO)

18.WebSocket技术

WebSocket 的核心特点

  1. 持久化连接:一旦握手成功,TCP 连接会一直保持,为后续通信复用。
  2. 全双工通信:客户端和服务器可以同时独立地发送数据,就像打电话一样,双方可以同时说话。
  3. 低开销:在建立连接后,数据传输的头部信息(帧头)非常小(通常只有 2-10 字节),远小于 HTTP 头部(通常有几百字节到几KB),极大地减少了网络带宽的消耗。
  4. 服务器主动推送:这是 WebSocket 最核心的价值。服务器可以在任何需要的时候,主动将数据推送给客户端,而不需要客户端傻傻地反复询问。

    一个简单的 JavaScript 客户端示例

在浏览器中,WebSocket API 使用起来非常简单。

// 1. 创建 WebSocket 连接,连接到服务器地址
const socket = new WebSocket('wss://echo.websocket.org'); // wss 是加密的 WebSocket,相当于 HTTPS

// 2. 监听连接打开事件
socket.onopen = function(event) {
  console.log('连接已建立');
  // 连接成功后,发送一条消息
  socket.send('你好,服务器!');
};

// 3. 监听服务器发送来的消息
socket.onmessage = function(event) {
  console.log('收到服务器消息:', event.data);
};

// 4. 监听连接关闭事件
socket.onclose = function(event) {
  console.log('连接已关闭');
};

// 5. 监听错误事件
socket.onerror = function(error) {
  console.error('WebSocket 错误:', error);
};

// 在需要的时候,可以手动关闭连接
// socket.close();

19.反向代理和正向代理

  • 正向代理:如科学上网,你要访问油管,但是得找一个代理人,它帮你连上油管。
    YouTube 不知道是谁真正访问了它,它只知道是那个代理服务器在访问。
    所以,正向代理可以隐藏客户端的身份 你(客户端)是明确知道代理存在的,并且需要主动配置。
  • 反向代理:谷歌每天接受大量的访问,会有很多台服务器处理不同人的访问请求。访问人与代理人连接,代理人去与服务器对接,但是访问人不知道自己最终访问的是哪一台服务器。
    你不知道真正处理你请求的是哪台服务器。你始终只和反向代理打交道。所以,反向代理可以隐藏后端服务器的身份和信息,增加安全性。
    你(客户端)不需要做任何特殊配置,对你来说整个过程是完全透明的。

总结对比

特性正向代理反向代理
代理对象客户端服务器端
配置方客户端需要主动配置客户端无感知,无需配置
隐藏对象隐藏客户端的身份隐藏后端服务器的身份
典型场景科学上网、公司内网代理大型网站(如Google,淘宝)的负载均衡、CDN
比喻秘书/翻译(为你服务)前台/总管(为公司服务)

20.Apache POI介绍

Apache POI是一个用于创建和操作 Microsoft Office 格式文件的 Java API,是 Java 生态中处理 Office 文档的标准解决方案。 ## 核心 API 概览

类/接口用途
Workbook工作簿接口,XSSFWorkbook/HSSFWorkbook 的父类
Sheet工作表,代表Excel的一个sheet页
Row行,代表工作表的一行
Cell单元格,存储实际数据
CellStyle单元格样式,控制字体、颜色、边框等
FormulaEvaluator公式计算器

正确流程:设置响应头 → 创建Workbook → 写入数据 → workbook.write() → 自动关闭资源