全网首发AI+JavaWeb开发入门,Tlias教学管理系统项目实战全套视频教程,从需求分析、设计、前后端开发、测试、程序优化到项目部署一套搞定
黑马官方笔记
🧠 Web 开发初学者导学笔记
一、什么是 Web?
二、Web 开发要学什么?(课程安排)
📌 Part1:前端基础(2天)
- HTML / CSS / JS
- Ajax / Axios
- Vue3 基础
📌 Part2:后端基础(4天)
- Maven 项目管理
- HTTP 协议,IOC/DI
- MySQL、JDBC、MyBatis
📌 Part3:后端实战(6天)
- 员工/学员/班级/报表管理
- 登录认证等常见业务实现
📌 Part4:后端进阶(2天)
- AOP 面向切面编程
- SpringBoot原理、自定义Starter
- Maven高级技巧
📌 Part5:前端实战(4天)
- Vue 工程化开发
- ElementPlus UI 框架
- 实战案例(Tlias系统)
📌 Part6:部署上线(2天)
三、AI如何赋能Web开发?
开发环节 |
AI能做什么 |
设计页面 |
自动生成页面结构草图 |
编写代码 |
AI 辅助代码生成、单元测试、优化 |
Bug 修复 |
AI 快速定位并修复常见错误 |
前端开发 |
自动生成 Vue/HTML 代码,提升开发效率 |
解释代码 |
快速理解和学习已有项目代码 |
部署运维 |
AI 自动生成脚本,简化部署过程 |
四、课程特色(为什么选这门课?)
-
项目驱动教学:
-
全链路开发培养:
- 技术栈:SpringBoot3 + Vue3
- 从需求分析 → 设计 → 开发 → 测试 → 部署全流程掌握
-
AI 全面赋能:
-
企业级开发规范:
- 前后端分离
- 接口文档规范(30+)、模拟真实开发流程
五、学完能做什么?
✅ 前端页面开发能力
✅ 后端接口开发能力
✅ 数据库设计与使用能力
✅ 项目部署上线能力
✅ 独立完成中小型Web项目(SpringBoot3 + Vue3)
适合用于:
六、学习建议
- 每天至少实践一个小模块,动手写代码
- 多使用 AI 工具(如 ChatGPT、Copilot)辅助理解与开发
- 养成良好开发规范(注释清晰、命名规范、结构合理)
- 多复习总结,形成自己的学习笔记和项目经验
🧠 Web 前端开发 Day01 入门笔记(HTML + CSS)
一、什么是前端?
二、HTML 基础知识
✅ HTML 是什么?
✅ HTML 骨架示例
<html>
<head>
<title>页面标题</title>
</head>
<body>
<h1>Hello HTML</h1>
<img src="img/1.png">
</body>
</html>
✅ 常见标签
标签 |
功能说明 |
<h1> ~<h6> |
标题(h1最大,h6最小) |
<p> |
段落文本 |
<img> |
图片展示,使用 src 属性 |
<a> |
超链接,使用 href 和 target |
<form> |
表单容器 |
<input> |
表单项(文本框、密码框等) |
<select> |
下拉列表 |
<textarea> |
文本域 |
<table> |
表格 |
三、CSS 样式基础
✅ CSS 是什么?
- 全称:Cascading Style Sheets(层叠样式表)
- 功能:控制网页的外观样式
✅ 三种CSS写法
写法 |
示例 |
行内样式 |
<h1 style="color:red">标题</h1> |
内部样式 |
<style> h1 { color:red; } </style> |
外部样式表文件 |
<link rel="stylesheet" href="style.css"> |
✅ 常见样式属性
属性 |
说明 |
color |
字体颜色 |
font-size |
字体大小 |
background |
背景颜色或图片 |
text-align |
文本对齐方式 |
margin |
外边距 |
padding |
内边距 |
width / height |
宽度 / 高度 |
四、CSS 选择器基础
选择器类型 |
写法 |
作用对象 |
元素选择器 |
h1 {} |
所有 h1 元素 |
类选择器 |
.box {} |
所有 class=“box” 元素 |
ID 选择器 |
#top {} |
id=“top” 的唯一元素 |
📌 优先级:ID选择器 > 类选择器 > 元素选择器
五、盒子模型与页面布局
✅ 什么是盒子模型?
所有HTML元素都可以看成一个“盒子”,由以下4部分组成:
margin(外边距)
border(边框)
padding(内边距)
content(内容)
✅ 常用布局标签
标签 |
特点说明 |
<div> |
块级元素,一行一个,可设置宽高 |
<span> |
行内元素,一行多个,不可设置宽高 |
六、Flex 弹性布局
七、表单与表格基础
✅ 表单结构
<form action="/submit" method="post">
<input type="text" name="username">
<input type="password" name="password">
<button type="submit">提交</button>
</form>
action
:提交目标地址
method
:GET(拼接在URL)或 POST(提交到请求体)
✅ 表格结构
<table>
<thead>
<tr><th>姓名</th><th>年龄</th></tr>
</thead>
<tbody>
<tr><td>张三</td><td>25</td></tr>
</tbody>
</table>
八、路径书写基础
类型 |
示例 |
绝对路径 |
https://xxx.com/a.png |
相对路径 |
./img/a.png (当前目录) |
上级目录路径 |
../img/a.png |
✅ 总结
- HTML 负责结构:用于定义页面的标题、段落、图像、链接等基础内容
- CSS 负责样式:控制页面的字体、颜色、布局、间距等外观
- 网页开发核心:先写结构,再美化样式,逐步掌握页面排版与布局技巧
- 从页面到项目:本节掌握的知识是构建完整网页和后续实战的基础
🧠 前端开发 Day02 学习笔记(JavaScript + Vue3)
一、JavaScript 基础入门
✅ 什么是 JavaScript?
- 一种脚本语言,用于控制网页的行为(交互)
- 运行在浏览器中,实现页面点击、响应、动画等功能
- 与 Java 完全不同,只是语法类似
✅ JavaScript 三大组成
组成部分 |
功能作用 |
ECMAScript |
JS 的核心语法规范(变量、函数等) |
BOM |
浏览器对象模型(控制浏览器行为) |
DOM |
文档对象模型(操作网页结构内容) |
✅ JavaScript 引入方式
引入方式 |
示例说明 |
内部脚本 |
<script>...</script> 写在HTML中 |
外部脚本 |
<script src="main.js"></script> 引入.js 文件 |
✅ 变量与常量
- 声明变量:
let name = 'Tom'
- 声明常量:
const PI = 3.14
- JS 是弱类型语言:变量可以随时更换数据类型
✅ 数据类型
类型 |
示例 |
number |
1, 3.14, NaN |
boolean |
true / false |
string |
‘hello’, “world”, 模板字符串 |
null |
空对象 |
undefined |
未赋值变量 |
🧪 查看类型:typeof 变量
✅ 函数
function greet(name) {
return "Hello " + name;
}
- 匿名函数:
const fn = function() { ... }
- 箭头函数:
const fn = () => { ... }
✅ 对象与 JSON
let person = {
name: "Tom",
age: 20,
sayHi() {
console.log("Hi");
}
};
{ "name": "Tom", "age": 20 }
-
转换方法:
JSON.stringify(obj)
→ 转为字符串
JSON.parse(str)
→ 转为对象
✅ DOM 操作
-
获取元素:
document.querySelector('#id')
document.querySelectorAll('.class')
-
修改内容:
element.innerText = '新内容'
element.style.color = 'red'
✅ 事件监听
element.addEventListener('click', function() {
});
常见事件:
click
:点击
mouseenter
/ mouseleave
:移入/移出
input
:输入框变化
submit
:表单提交
二、Vue3 基础入门
✅ 什么是 Vue?
- 一种渐进式前端框架,用于构建交互式页面
- 强调数据驱动视图
- 优点:提升开发效率、维护方便
✅ 使用 Vue 的基本步骤
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
createApp({
data() {
return {
message: 'Hello Vue'
}
}
}).mount('#app')
</script>
<div id="app">
<h1>{{ message }}</h1>
</div>
三、Vue 常用指令
🔁 v-for
列表渲染
<li v-for="(item, index) in items" :key="item.id">{{ item.name }}</li>
🔗 v-bind
动态绑定属性
<img :src="item.image" />
🎭 条件渲染:v-if
vs v-show
指令 |
原理与使用场景 |
v-if |
控制是否创建元素(适合不频繁切换) |
v-show |
控制显示隐藏(适合频繁切换) |
<span v-if="gender === 1">男</span>
<span v-else-if="gender === 2">女</span>
<span v-else>未知</span>
📥 表单数据绑定:v-model
<input v-model="username" />
🖱️ 事件绑定:v-on
或简写 @
<button @click="doSomething">提交</button>
四、Vue 中的 Ajax 异步交互
✅ 什么是 Ajax?
- 异步 JavaScript 和 XML 的缩写
- 可以在不刷新页面的前提下与服务器交换数据
✅ 使用 Axios(推荐)
axios.get(url)
.then(response => { ... })
.catch(error => { ... })
可配合 async / await
写法提升可读性。
五、Vue 生命周期简述
Vue 组件从创建到销毁的过程叫做生命周期,每个阶段都可以挂载函数(钩子):
-
常用钩子函数:
mounted()
:页面加载完毕后自动执行(常用于发起 Ajax 请求)
created()
、updated()
等等
✅ 总结
技术 |
作用 |
JavaScript |
控制网页交互,掌握语法、DOM、事件是基础 |
Vue3 |
构建复杂页面、提高效率,掌握数据绑定、事件监听、条件渲染等核心指令 |
Axios |
实现前后端数据通信的利器,便于异步请求服务器 |
本次内容为后续开发企业级项目打下基础。掌握这些内容后,就可以开始构建完整的“员工管理系统”前端页面。
🧠 Web 后端开发 Day03 学习笔记:Maven 入门基础
一、什么是 Maven?
✅ Maven 的主要作用:
功能 |
说明 |
编译 |
将源码编译为字节码 |
测试 |
使用 JUnit 等工具执行单元测试 |
打包 |
将项目打包为 jar/war |
安装 |
安装到本地仓库,供其他项目引用 |
发布 |
部署到远程仓库(私服),供团队/公司共享 |
二、Maven 的核心概念
概念 |
说明 |
POM |
项目对象模型(Project Object Model) |
依赖 |
当前项目运行所需的 jar 包 |
插件 |
用于编译、测试、打包、部署等工作的工具 |
仓库 |
用于存放 jar 包的地方 |
📦 Maven 的三类仓库:
- 本地仓库:位于用户本机(默认路径可配置)
- 远程仓库:可配置的服务器仓库(如私服)
- 中央仓库:Maven 官方公共仓库
三、Maven 安装步骤
-
解压 apache-maven-x.x.x-bin.zip
-
修改 conf/settings.xml
-
配置环境变量
MAVEN_HOME
:Maven 安装目录
- 加入 PATH:
%MAVEN_HOME%\bin
-
检查安装是否成功:mvn -v
四、在 IDEA 中使用 Maven
✅ 创建 Maven 项目
- New Project → 选择 Maven → 配置项目信息(groupId, artifactId, version)
✅ Maven 坐标(唯一标识一个依赖)
坐标元素 |
说明 |
groupId |
项目组织名,通常为公司域名的反写 |
artifactId |
模块名,如 order-service、user-api 等 |
version |
项目版本,常用 SNAPSHOT 或 RELEASE |
✅ 导入已有 Maven 项目
- File → Project Structure → Modules → 导入 pom.xml
- 或使用 Maven 面板 → + 添加项目
五、依赖管理
- 所有依赖配置在
pom.xml
文件中,格式如下:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.1</version>
</dependency>
</dependencies>
🧩 依赖排除:
可使用 <exclusions>
标签手动排除传递性依赖。
六、生命周期与命令
✅ Maven 三大生命周期
生命周期 |
说明 |
clean |
清理项目构建产生的文件 |
default |
项目主要构建流程 |
site |
生成项目文档、报告等 |
✅ default 生命周期常用阶段
阶段 |
功能说明 |
compile |
编译主代码 |
test |
执行单元测试 |
package |
打包成 jar 或 war 文件 |
install |
安装到本地仓库 |
deploy |
部署到远程仓库 |
命令示例(终端或 Maven 面板都可执行):
mvn clean
mvn compile
mvn package
七、单元测试与 JUnit
✅ 单元测试流程
- 在
test/java
目录中创建测试类
- 添加依赖(如 JUnit 5)
- 编写测试方法,使用
@Test
注解
- 运行测试,查看绿色(成功)或红色(失败)
✅ 常用注解
注解 |
作用说明 |
@Test |
测试方法 |
@BeforeEach |
每个测试前执行一次初始化操作 |
@AfterEach |
每个测试后执行清理操作 |
@BeforeAll |
所有测试前执行一次初始化 |
@AfterAll |
所有测试后执行清理操作 |
✅ 断言(Assertions)
用于验证预期结果:
Assertions.assertEquals(4, calculator.add(2,2));
八、依赖范围(scope)
范围 |
使用位置 |
compile |
默认,主程序和测试都可用 |
test |
仅在测试代码中可用 |
provided |
编译需要,运行由容器提供(如Servlet) |
runtime |
编译不需要,运行时需要 |
九、常见问题解决方案
❌ 问题:依赖下载失败,.lastUpdated
文件存在
✅ 解决:
- 删除仓库中对应的
.lastUpdated
文件
- 或使用命令一键清理:
del /s *.lastUpdated
✅ 总结
模块 |
学习重点 |
Maven 作用 |
项目构建、依赖管理、统一结构 |
核心概念 |
POM、依赖、插件、生命周期、仓库 |
实际使用 |
IDEA中创建项目、引入依赖、执行生命周期命令 |
单元测试 |
使用 JUnit 进行功能测试,生成绿色报告,提高代码质量 |
常见问题处理 |
.lastUpdated 清理、依赖范围控制、私服配置等 |
掌握 Maven,是进入 Java 后端开发体系的关键步骤,也是整个 Web 项目开发和部署的基础保障。
🧠 Day04:Web 后端开发基础笔记
一、Web 架构基础
✅ 静态资源 vs 动态资源
类型 |
内容特点 |
静态资源 |
页面内容固定,不随用户变化,如:HTML、CSS、JS、图片 |
动态资源 |
内容根据请求动态生成,如:Servlet、JSP、接口响应 |
✅ 架构模式对比
架构 |
简称 |
特点 |
浏览器/服务器 |
B/S |
客户端只需浏览器,维护方便 |
客户端/服务器 |
C/S |
客户端需独立安装,体验更好但维护难 |
二、SpringBoot Web 开发入门
✅ 项目创建流程
- 创建 SpringBoot 工程,选择
Web
依赖
- 编写控制器类
HelloController
:
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping
public String hello(String name) {
return "Hello " + name;
}
}
- 启动程序 → 访问
http://localhost:8080/hello?name=Heima
✅ 注解说明
注解 |
含义 |
@RestController |
表示该类是 Web 控制器(包含返回体) |
@RequestMapping |
设置类或方法的访问路径 |
✅ 启动原理
- 使用
main()
方法即可启动,背后由 SpringBoot 提供的自动配置完成初始化
- 使用内嵌的 Tomcat 容器,直接运行即可对外提供服务
三、HTTP 协议基础
✅ 什么是 HTTP?
- 全称:Hyper Text Transfer Protocol
- 作用:规定浏览器与服务器之间如何交换数据
- 特点:基于 TCP、无状态、一次请求对应一次响应
✅ HTTP 请求结构
组成部分 |
示例 |
请求行 |
GET /hello?name=Tom HTTP/1.1 |
请求头 |
User-Agent: Chrome 等键值对信息 |
请求体 |
通常用于 POST,包含表单或 JSON 数据 |
常见请求方式:
方法 |
特点 |
GET |
参数放在 URL 上,有长度限制 |
POST |
参数放在请求体中,无长度限制 |
✅ HTTP 响应结构
部分 |
说明 |
响应行 |
HTTP/1.1 200 OK |
响应头 |
例如 Content-Type |
响应体 |
实际返回的 HTML 或 JSON 数据 |
响应状态码分类:
- 1xx:处理中
- 2xx:成功(如 200)
- 3xx:重定向(如 302)
- 4xx:客户端错误(如 404)
- 5xx:服务器错误(如 500)
四、Web 案例:用户列表展示
✅ 开发流程
- 准备数据文件(user.txt)和前端页面
- 创建实体类 User 封装数据
- 编写 Controller 处理
/list
请求
- 使用
@ResponseBody
返回 JSON 数据给前端
具体实现参考用 IntelliJ + Spring Boot + Lombok 实现用户列表展示,注意这个是前后端不分离的
五、分层架构与解耦设计
✅ 三层架构职责
层级 |
作用说明 |
Controller |
控制层:接收请求,返回响应 |
Service |
业务层:处理业务逻辑 |
DAO / Mapper |
数据层:访问数据库 |
✅ 三层架构优点
- 职责单一,复用性强
- 易于维护,逻辑清晰
- 实现高内聚、低耦合设计原则
六、IOC 与 DI(依赖注入)
✅ 术语解释
概念 |
说明 |
IOC |
控制反转:对象的创建交给容器 |
DI |
依赖注入:容器自动将依赖对象注入进来 |
Bean |
被 Spring 管理的组件对象 |
✅ 常用注解
注解 |
用途 |
@Component |
普通 Bean 类 |
@Service |
业务类(用于 Service 层) |
@Repository |
数据类(用于 DAO 层) |
@Controller |
控制器类 |
@Autowired |
自动按类型注入 Bean 对象 |
@Qualifier |
按名称指定注入的 Bean |
@Resource |
按名称注入(JavaEE 标准) |
所有注解生效的前提是:被 SpringBoot 的组件扫描机制扫描到
(默认扫描启动类所在包及其子包)
✅ DI 的三种方式
方式 |
特点说明 |
属性注入 |
简洁快速,但不利于封装性 |
构造注入 |
依赖清晰,推荐使用(支持必注) |
Setter注入 |
适用于可选依赖,提高可维护性 |
✅ 总结
模块 |
关键知识 |
Web 架构 |
理解静态与动态资源,熟悉 B/S 架构 |
HTTP 协议 |
掌握请求/响应格式、状态码意义、请求方式差异 |
SpringBoot Web |
能独立创建工程、定义控制器、响应数据 |
三层架构 |
掌握 Controller-Service-DAO 职责划分 |
IOC & DI |
理解控制反转和依赖注入,掌握相关注解使用方式 |
🧠 Day05:数据库基础学习笔记(MySQL + SQL)
一、什么是数据库?
- 数据库(Database / DB):存储和管理数据的仓库。
- 数据库管理系统(DBMS):用于操作数据库的软件,如 MySQL、Oracle。
- SQL(Structured Query Language):结构化查询语言,是操作关系型数据库的标准语言。
二、常见数据库产品
数据库 |
特点 |
MySQL |
开源、轻量级、使用广泛 |
Oracle |
商业化,性能强,费用高 |
PostgreSQL |
开源,支持复杂查询 |
SQLite |
嵌入式、轻量级,无需安装 |
三、MySQL 基础
✅ 安装与连接
mysql -h 主机 -P 端口 -u 用户名 -p 密码
✅ 数据模型(关系型数据库)
- 数据以 二维表 的形式存储
- 一个数据库中可以有多张表,每张表包含若干记录(行)
四、SQL 语句分类
类别 |
全称 |
作用 |
DDL |
Data Definition Language |
定义数据库结构(库、表) |
DML |
Data Manipulation Language |
操作数据记录(增删改) |
DQL |
Data Query Language |
查询数据记录 |
五、DDL(定义语言)
✅ 创建数据库
CREATE DATABASE 数据库名;
✅ 创建表(含字段约束)
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
gender CHAR(1) DEFAULT '男',
age INT,
hire_date DATE
);
✅ 常见字段约束
关键字 |
含义 |
PRIMARY KEY |
主键,唯一且非空 |
NOT NULL |
非空 |
UNIQUE |
唯一 |
DEFAULT |
默认值 |
AUTO_INCREMENT |
自增主键 |
六、DML(数据操作)
✅ 插入数据
INSERT INTO emp(name, gender, age) VALUES ('Tom', '男', 25);
✅ 更新数据
UPDATE emp SET age = 30 WHERE name = 'Tom';
✅ 删除数据
DELETE FROM emp WHERE age < 18;
七、DQL(查询语言)
✅ 基本查询
SELECT name, age FROM emp;
✅ 条件查询
SELECT * FROM emp WHERE age >= 30 AND gender = '男';
-
比较符号:=
, !=
, <
, >
, BETWEEN
, IN
, LIKE
, IS NULL
-
模糊匹配:
✅ 分组查询(+聚合函数)
SELECT gender, COUNT(*) FROM emp GROUP BY gender;
✅ 排序查询
SELECT * FROM emp ORDER BY age DESC, name ASC;
✅ 分页查询
SELECT * FROM emp LIMIT 0, 10;
-
LIMIT 起始索引, 每页条数
-
索引从 0 开始,一般由页码换算得:
八、表结构操作(DDL)
DESC emp;
ALTER TABLE emp ADD phone VARCHAR(20);
ALTER TABLE emp MODIFY age TINYINT;
ALTER TABLE emp DROP COLUMN phone;
DROP TABLE emp;
九、数据类型(MySQL 常见)
类型 |
示例 |
说明 |
INT / BIGINT |
1, 10000 |
整数 |
FLOAT / DOUBLE |
3.14, 9.99 |
浮点数 |
CHAR(n) |
‘男’, ‘Y’ |
固定长度字符串,节省空间 |
VARCHAR(n) |
‘张三’, ‘admin’ |
可变长度字符串 |
DATE |
‘2024-01-01’ |
日期 |
DATETIME |
‘2024-01-01 10:00:00’ |
日期+时间 |
🔟 数据库建表设计示例
以员工管理系统为例,分析页面字段,设计如下表结构:
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
gender CHAR(1) DEFAULT '男',
age TINYINT,
job VARCHAR(20),
entry_date DATE,
create_time DATETIME,
update_time DATETIME
);
✅ 总结
模块 |
核心内容说明 |
数据库 |
存储数据的仓库,使用 DBMS 管理 |
SQL |
操作数据库的标准语言,分 DDL、DML、DQL |
表设计 |
明确字段类型、约束,结构合理便于查询与维护 |
查询技巧 |
掌握 where、group by、order by、limit 等语法 |
工具推荐 |
图形化工具如 DataGrip 提高效率 |
掌握本节内容后,你就能进行基础的数据建模、表结构设计和数据操作,为后端开发打下坚实的基础。
📘 Day06 后端 Web 基础:Java 操作数据库详解笔记
一、Java 操作数据库的两种方式
技术 |
简介 |
JDBC |
Java 官方提供的一套数据库操作 API |
MyBatis |
简化 JDBC 操作的框架,封装更高级易用 |
二、JDBC 全称与原理
✅ 全称:Java Database Connectivity
是一组用于访问关系型数据库的标准 API 接口
✅ 原理图:
Java 程序 ---调用---> JDBC 接口(统一规范)
↓
数据库驱动实现类
↓
实际连接并操作数据库(如 MySQL)
JDBC 本身是接口,数据库厂商(如 MySQL)提供对应的驱动 jar 实现。
三、使用 JDBC 操作数据库的七个步骤
🔧 案例目标:更新用户表中 ID 为 1 的用户年龄为 25
UPDATE user SET age = 25 WHERE id = 1;
✅ 1. 添加 Maven 依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
✅ 2. 注册数据库驱动(新版可省略)
Class.forName("com.mysql.cj.jdbc.Driver");
✅ 3. 获取数据库连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/dbname?serverTimezone=UTC", "root", "password");
✅ 4. 定义 SQL
String sql = "UPDATE user SET age = 25 WHERE id = 1";
✅ 5. 获取 Statement 并执行 SQL
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(sql);
✅ 6. 处理结果(DML:查看是否成功;DQL:遍历结果集)
✅ 7. 释放资源
stmt.close();
conn.close();
四、JDBC 查询数据(DQL)
🎯 目标:根据用户名和密码查询用户
SELECT * FROM user WHERE username = 'daqiao' AND password = '123456';
✅ 执行与解析
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
String username = rs.getString("username");
int age = rs.getInt("age");
}
rs.next()
:将光标向下移动,判断是否有下一条记录
rs.getXxx("列名")
:获取对应列的数据
五、预编译 SQL:PreparedStatement
🛡️ 为什么推荐?
- 防止 SQL 注入
- 提升性能(SQL 只编译一次)
✅ 示例:防止注入的写法
String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "admin");
ps.setString(2, "123456");
ResultSet rs = ps.executeQuery();
六、MyBatis 简介
- MyBatis 是一个持久层框架
- 核心目的:简化 JDBC 操作
- 支持 注解式 SQL 和 XML 映射文件
七、SpringBoot 集成 MyBatis 步骤
✅ 准备阶段
- 创建 SpringBoot 项目
- 加入依赖(MyBatis Framework、MySQL Driver 、Lombok)
- 配置 application.properties 连接数据库
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=1234
- 创建数据库表
user
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '主键,自增',
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
`password` VARCHAR(100) NOT NULL COMMENT '登录密码(通常存储哈希值)',
`name` VARCHAR(50) DEFAULT NULL COMMENT '用户真实姓名',
`age` INT DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_unicode_ci
COMMENT='用户表';
INSERT INTO `user` (username, password, name, age) VALUES
('zhangsan', 'zhangsan123', '张三', 28),
('lisi', 'lisi123', '李四', 32),
('wangwu', 'wangwu123', '王五', 25),
('zhaoliu', 'zhaoliu123', '赵六', 30),
('tianqi', 'tianqi123', '田七', 27);
SELECT * FROM `user`;
- 创建实体类
User
package com.example.pojo;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
private String name;
private Integer age;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
✅ 编写 Mapper 接口(注解方式)
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User findById(int id);
}
- 使用
@Mapper
告诉 SpringBoot 它是 MyBatis 接口
#{}
用于占位(会自动转换为预编译 SQL)
✅ 执行增删改查
操作 |
注解 |
查询 |
@Select(...) |
插入 |
@Insert(...) |
更新 |
@Update(...) |
删除 |
@Delete(...) |
示例:
@Select("SELECT * FROM user WHERE id = #{id}")
User findById(int id);
@Select("SELECT * FROM user")
List<User> findAll();
@Select("SELECT * FROM user WHERE username = #{username}")
User findByUsername(String username);
@Insert("INSERT INTO user(username, password, name, age) VALUES(#{username}, #{password}, #{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);
@Update("UPDATE user SET username = #{username}, password = #{password}, name = #{name}, age = #{age} WHERE id = #{id}")
int updateUser(User user);
@Delete("DELETE FROM user WHERE id = #{id}")
int deleteById(int id);
✅ 单元测试
@SpringBootTest
class MybatisProjectApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testFindAll(){
User byId = userMapper.findById(1);
System.out.println(byId);
}
}
八、MyBatis 中 # 和 $ 的区别(重要)
符号 |
含义 |
推荐情况 |
#{} |
占位符,防 SQL 注入,自动转义 |
✅ 推荐 |
${} |
字符串拼接,可能引起注入 |
⚠️ 小心使用,如表名、列名动态时 |
九、数据库连接池
- 是用于管理数据库连接的容器(Connection 的复用)
- SpringBoot 默认连接池:HikariCP
- 常用产品:Druid(阿里)、C3P0、DBCP
✅ 优势:
- 节省资源,避免频繁创建连接
- 提升系统响应速度
- 防止连接泄漏
🔟 XML 映射方式(用于复杂 SQL)
✅ 映射规则:
- Mapper 接口与 XML 文件同名、同包
- XML 中的
namespace
为接口全限定名
- SQL 的
id
对应接口的方法名
<mapper namespace="com.example.mapper.UserMapper">
<select id="findAll" resultType="User">
SELECT * FROM user
</select>
</mapper>
🧩 SpringBoot 配置文件格式
格式 |
特点 |
.properties |
传统格式,键值对 |
.yml/.yaml |
缩进结构,语义清晰 ✅ 推荐 |
✅ yml 基本语法:
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/db
username: root
password: root
- 用空格缩进,不能用 tab
#
表示注释
- 支持对象、数组、嵌套结构定义
✅ 总结表格:JDBC vs MyBatis
对比点 |
JDBC |
MyBatis |
操作方式 |
繁琐,需要手动写连接、SQL、解析 |
简洁,封装了 SQL 及映射 |
安全性 |
需要手动防止注入 |
自动预编译(#{} )更安全 |
学习成本 |
偏底层,细节多 |
上手快,逻辑清晰 |
推荐使用场景 |
轻量测试、了解底层原理 |
实际项目开发中广泛使用 |
🧠 Day07 后端 Web 实战笔记(部门管理模块)
一、项目背景与目标
开发 Tlias 智能学习辅助系统中的“部门管理”模块,实现以下功能:
- ✅ 查询部门列表
- ✅ 删除部门
- ✅ 新增部门
- ✅ 修改部门
- ✅ 日志记录
二、开发模式与项目架构
✅ 采用 前后端分离架构
对比 |
前后端混合开发 |
前后端分离开发(推荐) |
部署模式 |
前后端一体 |
前后端独立部署 |
维护性 |
差,不易扩展 |
高,职责清晰,接口对接规范 |
开发流程 |
串行 |
并行(前后端各自独立、通过接口联调) |
✅ 开发流程
需求分析 → 接口设计 → 前后端并行开发 → 接口测试 → 联调部署
三、RESTful 风格接口设计
✅ 核心思想
- 用 URL 表示资源(Resource)
- 用 HTTP 动词表示操作(行为)
动作 |
HTTP 方法 |
URL 示例 |
查询 |
GET |
/depts |
删除 |
DELETE |
/depts?id=8 |
新增 |
POST |
/depts |
修改 |
PUT |
/depts |
查询单个 |
GET |
/depts/{id} |
四、接口测试工具:Apifox
-
官网:https://apifox.com/
-
作用:
- 编写和管理 API 文档
- 调试 API 请求(支持 GET/POST/PUT/DELETE)
- 生成 Mock 数据
-
✅ 推荐用于前后端并行开发过程中的调试接口使用
五、部门管理功能实现
✅ 三层架构职责
层 |
职责说明 |
Controller |
接收请求,参数绑定,响应数据 |
Service |
处理业务逻辑 |
Mapper |
访问数据库,执行 SQL |
tlias-web-management/ ← 项目根目录
├─ .idea/ ← IntelliJ IDEA 的项目配置(.iml、workspace 等)
├─ .mvn/ ← Maven Wrapper,用于锁定 Maven 版本并保证每个人用同一版本构建
├─ pom.xml ← Maven 项目描述文件
├─ src/
│ ├─ main/
│ │ ├─ java/
│ │ │ └─ com.example/ ← 基础包
│ │ │ ├─ TliasWebManagementApplication.java
│ │ │ │ // Spring Boot 启动类,带 @SpringBootApplication
│ │ │ ├─ controller/ ← Web 层:接收 HTTP 请求、组装参数、返回结果
│ │ │ │ └─ DeptController.java
│ │ │ ├─ service/ ← 业务层接口,定义系统要做的事情
│ │ │ │ └─ DeptService.java
│ │ │ ├─ service/impl/ ← 业务层接口的实现,写具体的业务逻辑
│ │ │ │ └─ DeptServiceImpl.java
│ │ │ ├─ mapper/ ← MyBatis 层:定义数据库操作接口(@Mapper)
│ │ │ │ └─ DeptMapper.java
│ │ │ └─ pojo/ ← 用于封装数据的简单 Java 对象(实体/DTO)
│ │ │ ├─ Dept.java
│ │ │ └─ Result.java
│ │ └─ resources/
│ │ └─ application.yml ← YAML 格式,Spring Boot + 数据库 + MyBatis 等的配置
│ └─ test/ ← 单元测试代码目录
└─ target/ ← 构建产物(class、jar 等,由 mvn 自动生成)


六、查询部门列表
✅ SQL:
SELECT * FROM dept ORDER BY update_time DESC;
✅ MyBatis 自动封装规则:
字段名情况 |
是否自动封装 |
和实体类属性名一致 |
✅ 是 |
不一致,但符合驼峰命名规则 |
✅ 是 |
完全不一致 |
❌ 否,需要手动配置映射 |
✅ 手动映射方式:
- 使用 @Results + @Result
- 或在 SQL 中起别名
- 或在配置中开启驼峰映射开关(推荐)
七、前后端联调:Nginx 反向代理
✅ 场景
前端访问地址:http://localhost:90/api/depts
后端接口地址:http://localhost:8080/depts
✅ Nginx 配置示例
server {
listen 90;
location ^~ /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:8080;
}
}
✅ 原理
客户端请求 Nginx → Nginx 转发到后端 → 后端返回响应 → Nginx 返回前端
八、删除部门接口
✅ 请求格式
DELETE /depts?id=8
✅ 参数获取方式(推荐使用最后一种)
方式 |
示例代码 |
HttpServletRequest |
request.getParameter("id") |
@RequestParam |
@RequestParam("id") Integer id |
同名绑定 |
public Result delete(Integer id) ✅ 推荐 |
⚠️ 注意:@RequestParam
默认 required=true,必须传值


九、新增部门接口
✅ 请求格式(POST JSON 数据)
POST /depts
{
"name": "教研部"
}
✅ 参数绑定
- 使用实体类接收 JSON 格式请求体
- 配合
@RequestBody
注解
public Result insert(@RequestBody Dept dept) {
...
}


🔟 修改部门接口
✅ 需求拆解
-
根据 ID 查询回显
GET /depts/{id}
- 使用
@PathVariable
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) { ... }


-
修改后提交
PUT /depts
- JSON 格式,使用
@RequestBody
@PutMapping
public Result update(@RequestBody Dept dept) { ... }


11. 日志记录技术
✅ 日志的作用:
✅ 常见日志框架对比
框架 |
特点 |
JUL |
Java 自带,性能较弱 |
Log4j |
配置灵活,主流使用 |
Logback |
Log4j 的升级版,SpringBoot 默认 |
SLF4J |
日志门面(统一日志接口标准) |
✅ SpringBoot 默认使用 Logback
配置文件位置:logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %p %c - %m%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
✅ 日志级别(从低到高)
trace < debug < info < warn < error
✅ 使用方式
@Slf4j
public class DeptController {
log.info("正在查询所有部门...");
log.error("发生异常:{}", e.getMessage());
}
✅ 总结表
模块 |
学习目标与关键点 |
项目架构 |
理解前后端分离与三层结构分工 |
接口设计 |
掌握 RESTful 风格设计规范(路径 + 方法) |
参数绑定 |
理解 RequestParam、PathVariable、RequestBody 的使用 |
数据封装 |
掌握 MyBatis 自动/手动映射字段的方式 |
反向代理 |
能配置 Nginx 实现前后端联调 |
日志技术 |
掌握 Logback 配置、使用与日志级别管理 |
🧠 Day08 后端 Web 实战笔记:员工管理模块(Tlias 系统)
一、需求总览
我们将基于 Tlias 智能学习系统,实现以下功能:
功能模块 |
涉及内容说明 |
多表设计 |
设计员工与部门的关系(多表关系建模) |
多表查询 |
编写内连接、外连接、子查询 SQL |
分页查询 |
实现员工列表分页 + 条件分页查询 |
请求接收 |
熟悉 @RequestParam、@DateTimeFormat、@RequestBody 等参数接收方式 |
程序优化 |
动态 SQL、请求参数封装对象等 |
二、【数据库建模】多表关系详解
✅ 三类多表关系
类型 |
示例案例 |
数据库实现方式 |
一对多 |
部门:员工 = 1:n |
在“多”的一方添加外键字段,关联“1”的主键 |
一对一 |
用户:身份证 = 1:1 |
任意一方添加外键,并添加 UNIQUE 限制 |
多对多 |
学生:课程 = n:n |
新建中间表,两个外键分别指向两张表的主键 |
✅ 部门与员工是一对多
- 每个员工属于一个部门(emp.dept_id → dept.id)
三、【数据库完整性】物理 vs 逻辑外键
类型 |
特点 |
物理外键 |
使用 FOREIGN KEY 声明外键,强一致性,但影响性能 ✅ 不推荐 |
逻辑外键 |
在业务逻辑中控制关联,删除/更新前检查 ✅ 推荐用于实际开发 |
四、【多表查询】内连接、外连接、子查询
✅ 内连接
SELECT * FROM emp e INNER JOIN dept d ON e.dept_id = d.id;
✅ 左外连接(左边全保留)
SELECT * FROM emp e LEFT JOIN dept d ON e.dept_id = d.id;
✅ 子查询
SELECT * FROM emp WHERE salary < (SELECT AVG(salary) FROM emp);
✅ 练习示例题
- 查询“教研部”中“男性”员工,入职时间 > 2011-05-01
- 查询工资低于公司平均工资的男性员工
- 查询人数 > 10 的部门名称
- 查询薪资 > 10000 且入职时间 > 2010-05-01 的“教研部”员工,按薪资降序
- 查询工资低于自己部门平均工资的员工
五、【分页查询】员工列表分页展示
✅ 涉及表:emp(员工)+ dept(部门)
✅ 三层职责拆解
层级 |
主要逻辑 |
Controller |
接收分页参数(page、pageSize),返回封装结果 |
Service |
调用分页工具 PageHelper,返回 PageResult |
Mapper |
编写分页 SQL + count SQL |


✅ SQL 示例
SELECT * FROM emp e LEFT JOIN dept d ON e.dept_id = d.id LIMIT ?,?;
SELECT COUNT(*) FROM emp e LEFT JOIN dept d ON e.dept_id = d.id;
✅ 分页请求示例
GET /emps?page=1&pageSize=10
✅ Controller 接收参数(设置默认值)
public Result list(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize) { ... }
六、【分页插件】使用 PageHelper 简化开发

✅ 步骤
- Maven 引入 PageHelper 依赖
- 定义Mapper接口的查询方法(无需考虑分页)
- 在 Service 层配置分页逻辑:
PageHelper.startPage(page, pageSize);
Page<Emp> pageData = (Page<Emp>) empMapper.selectByCondition(...);

✅ 注意
- 只能作用于紧随其后的第一条 SQL
- SQL 末尾不加分号
;
七、【条件分页查询】


✅ 请求格式示例
GET /emps?name=张&gender=1&begin=2021-01-01&end=2023-01-01&page=1&pageSize=10
✅ Controller 接收多个参数
public Result list(@RequestParam String name,
@RequestParam Integer gender,
@RequestParam @DateTimeFormat(pattern="yyyy-MM-dd") LocalDate begin,
@RequestParam @DateTimeFormat(pattern="yyyy-MM-dd") LocalDate end,
Integer page, Integer pageSize) { ... }
✅ SQL 条件拼接
SELECT * FROM emp
WHERE name LIKE ?
AND gender = ?
AND entry_date BETWEEN ? AND ?
ORDER BY update_time DESC
八、【参数接收优化】对象封装 vs queryString
方法 |
特点说明 |
多个参数 |
可用 queryString,使用 @RequestParam 一一接收 |
参数多时 |
推荐封装为对象,如 EmpQueryDTO,提高可维护性 |
public class EmpQueryDTO {
private String name;
private Integer gender;
private LocalDate begin;
private LocalDate end;
private Integer page;
private Integer pageSize;
}
九、【MyBatis 动态 SQL】 + 组合使用
✅ 场景:用户输入的查询条件不固定
<select id="list" resultType="Emp">
SELECT * FROM emp
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="gender != null">
AND gender = #{gender}
</if>
<if test="begin != null and end != null">
AND entry_date BETWEEN #{begin} AND #{end}
</if>
</where>
</select>
✅ 总结
模块 |
核心内容 |
多表设计 |
一对多/多对多关系建表设计、逻辑外键优先 |
多表查询 |
掌握内连接、左连接、子查询的写法与使用场景 |
分页查询 |
手动分页 vs PageHelper 插件简化分页操作 |
条件接收 |
结合 @RequestParam、@DateTimeFormat 灵活绑定 |
参数优化 |
参数封装对象 + 自动映射提升代码整洁性 |
动态 SQL |
MyBatis 使用 <if> + <where> 实现条件拼接,灵活高效 |
🧠 Day09 后端 Web 实战笔记(员工管理进阶)
一、新增员工功能实现
🎯 目标
- 接收前端传来的员工信息(含多条工作经历)
- 将员工基本信息写入 emp 表
- 将工作经历批量写入 emp_expr 表
✅ 开发流程
- 接收请求参数(JSON 格式)
- 调用 Service 方法处理
- 先保存基本信息(emp)
- 批量插入工作经历信息(emp_expr)
✅ SQL 示例
INSERT INTO emp (name, gender, ...) VALUES (...);
INSERT INTO emp_expr (emp_id, company, begin, end, job) VALUES (...), (...), (...);
✅ 批量插入工作经历(MyBatis 动态 SQL)
使用 <foreach>
标签循环插入:
<insert id="insertExprList">
INSERT INTO emp_expr (emp_id, company, begin, end, job)
VALUES
<foreach collection="list" item="expr" separator=",">
(#{expr.empId}, #{expr.company}, #{expr.begin}, #{expr.end}, #{expr.job})
</foreach>
</insert>
✅ 插入后获取主键 ID
@Insert("INSERT INTO emp (...) VALUES (...)")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(Emp emp);
二、Spring 事务管理
💡 场景问题
如果成功保存了 emp 表中的数据,却因异常没插入 emp_expr,会导致数据不一致。
👉 必须将两步操作放入一个事务中!
✅ 什么是事务(Transaction)?
- 一组操作,要么全部执行成功,要么全部失败
- 是数据库中保证数据一致性的机制
✅ 手动事务控制(了解)
START TRANSACTION;
COMMIT;
✅ SpringBoot 中事务控制(重点)
使用注解 @Transactional
@Service
public class EmpService {
@Transactional
public void saveEmp(Emp emp) {
empMapper.insert(emp);
empExprMapper.insertBatch(emp.getExprList());
}
}
✅ 异常回滚说明
- 默认:只回滚
RuntimeException
- 想回滚其他异常 → 设置 rollbackFor
@Transactional(rollbackFor = Exception.class)
✅ 事务传播行为(了解)
行为 |
说明 |
REQUIRED |
默认,加入当前事务 |
REQUIRES_NEW |
创建新事务,暂停旧事务 |
适用于:主方法 + 日志记录方法分别管理事务
✅ 实践扩展:记录新增日志
- 创建 emp_log 表 + 实体类 + Mapper
- 在新增员工时插入一条日志,无论成功或失败
三、文件上传
✅ 应用场景
- 上传头像、简历、图片等资源
- 广泛存在于社交、办公、学习等平台
3.1 本地存储上传
✅ 步骤
String fileName = multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("D:/upload/" + fileName));
⚠️ 注意
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB
3.2 阿里云 OSS 上传(企业推荐)
✅ OSS 简介
OSS(Object Storage Service)是阿里云提供的对象存储服务,支持上传图片、音频、视频等文件,提供外链访问。
✅ 使用步骤
- 注册阿里云账号并实名认证
- 充值并开通 OSS 服务
- 创建 Bucket(存储空间)
- 获取 AccessKey(ID + Secret)
- 安装官方 SDK,使用 Java 上传
可以参考官方文档:OSS Java SDK快速入门
✅ 项目集成流程
① 添加 SDK 依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
② 编写上传工具类
public class AliOssUtils {
public String upload(MultipartFile file) {
}
}
③ 上传接口
@PostMapping("/upload")
public Result upload(MultipartFile file) {
String url = aliOssUtils.upload(file);
return Result.success(url);
}
3.3 参数配置优化方式
方法 |
特点说明 |
@Value |
单个字段注入,适合少量配置 |
@ConfigurationProperties |
一次性绑定多个配置项到 Java Bean ✅ 推荐 |
✅ 示例
aliyun:
oss:
endpoint: xxx
accessKeyId: xxx
accessKeySecret: xxx
bucketName: xxx
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOssProperties {
private String endpoint;
private String accessKeyId;
...
}
✅ 总结表格
模块 |
核心内容 |
新增员工 |
拆分 emp、emp_expr 表,批量插入,注意主键回填 |
事务控制 |
使用 @Transactional,保证多表数据一致性,支持异常控制 |
文件上传 |
本地上传入门,阿里云 OSS 企业应用推荐,掌握 SDK 使用流程 |
参数注入方式 |
@Value 适用于少量,@ConfigurationProperties 适合批量注入 |
🧠 Day10 后端 Web 实战笔记(员工管理 · 进阶模块)
一、删除员工功能
🎯 需求说明
- ✅ 删除单个员工
- ✅ 批量删除多个员工
- ✅ 删除员工的同时删除其工作经历信息(emp_expr)

✅ 后端接口设计
DELETE /emps?ids=1,2,3
✅ Controller 参数接收方式
方式 |
示例代码 |
使用数组 |
public Result delete(Long[] ids) |
使用集合 |
public Result delete(List<Long> ids) ✅ 推荐 |
✅ SQL 执行逻辑
DELETE FROM emp WHERE id IN (?, ?, ?);
DELETE FROM emp_expr WHERE emp_id IN (?, ?, ?);
两张表都要清理,保持数据一致性,推荐在事务中处理。

二、修改员工信息
🎯 需求分析
- 查询员工信息(基本 + 工作经历)并回显到前端表单
- 修改后提交 → 更新两张表


✅ 步骤 1:查询回显
SELECT * FROM emp e
LEFT JOIN emp_expr ee ON e.id = ee.emp_id
WHERE e.id = ?;
✅ MyBatis 查询结果封装方式
方式 |
使用场景 |
resultType |
字段名与属性名一致 ✅ 推荐简单查询 |
resultMap |
字段名不一致或嵌套复杂对象时使用 |
✅ 步骤 2:更新员工信息
UPDATE emp SET ... WHERE id = ?;
DELETE FROM emp_expr WHERE emp_id = ?;
INSERT INTO emp_expr (...) VALUES (...), (...);
✅ MyBatis 优化 SQL
使用 <set>
标签动态拼接字段,避免 SQL 尾部逗号错误:
<update id="updateEmp">
UPDATE emp
<set>
<if test="username != null"> username = #{username}, </if>
...
</set>
WHERE id = #{id}
</update>
三、统一异常处理机制
🎯 为什么需要异常处理?
- 代码中不可避免会出现运行时异常、数据库异常、空指针等
- 默认异常堆栈信息不利于用户阅读或前端处理
✅ 三种处理方式对比
方式 |
是否推荐 |
说明 |
try-catch 局部处理 |
❌ 不推荐 |
代码臃肿、重复多 |
controller 层 try |
❌ 不推荐 |
会打破三层职责划分 |
全局异常处理器 |
✅ 推荐 |
解耦、统一处理、便于维护 |
✅ 全局异常处理器配置
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
log.error("全局异常捕获:", e);
return Result.error("系统异常,请稍后再试");
}
}
本质上是使用 @ControllerAdvice + @ResponseBody + @ExceptionHandler
。
四、员工信息统计(职位 & 性别)
🎯 统计目标
- 职位统计:每个岗位的员工数量
- 性别统计:男女员工占比

✅ 职位统计 SQL 示例
SELECT job, COUNT(*) AS count
FROM emp
GROUP BY job;
返回值结构:List<JobOption>
或 List<Map<String,Object>>
可用于饼图、柱状图等图形展示。

✅ 性别统计 SQL 示例
SELECT
IF(gender = 1, '男', '女') AS gender,
COUNT(*) AS count
FROM emp
GROUP BY gender;

✅ MySQL 常用函数说明
函数 |
作用说明 |
CASE |
多条件匹配,类似 switch/case |
IF(expr,a,b) |
条件表达式,expr 成立则返回 a,否则 b |
IFNULL(a,b) |
若 a 不为 null,返回 a,否则返回 b |
✅ 总结归纳表
模块 |
学习重点与实用技巧 |
删除员工 |
支持批量删除 + 工作经历清理,推荐使用集合参数,事务控制 |
修改员工 |
分步骤:回显 + 提交,注意工作经历删除再插入,动态 SQL 优化 |
异常处理 |
推荐使用全局异常处理器,统一日志输出与响应格式,提升开发效率 |
信息统计 |
熟练掌握 SQL 分组统计 + CASE/IF 等函数,结合图表进行数据可视化 |
🧠 Day11 后端 Web 项目实战笔记(综合开发)
一、实战项目概述
📌 项目名称:Tlias 智能学习系统(后端)
✅ 本次任务目标
围绕以下模块,完成后端功能的编码与调试:
模块名称 |
功能说明 |
班级管理 |
列表查询、新增班级、删除班级、修改班级 |
学员管理 |
查询学员、添加学员、删除学员、修改学员、违纪处理 |
数据统计 |
班级人数统计、学历结构统计 |
所有功能严格按照接口文档实现,并完成前后端联调
二、实战阶段要求
要求 |
说明 |
独立完成 |
每位成员需要真正完成模块功能开发 |
团队协作 |
小组内成员互帮互助,遇到问题先自己思考,再团队讨论 |
接口规范 |
接口入参、出参、返回值格式要完全参照接口文档 |
前后端联调 |
后端完成后,使用前端页面或 Apifox 进行接口联调与测试 |
过程记录 |
对功能实现过程中的 Bug、优化点、异常处理方式进行记录与总结 |
演示讲解 |
每组选一人汇报成果:功能演示 + 思路说明 + Bug 经验总结 |
三、开发模块建议实现方式
1. 班级管理模块
功能 |
说明 |
方法示例(Rest 风格) |
查询列表 |
分页 + 条件查询(名称、时间等) |
GET /classes?page=1&pageSize=10 |
新增班级 |
表单提交 JSON 数据 |
POST /classes |
删除班级 |
批量删除 |
DELETE /classes?ids=1,2,3 |
修改班级 |
查询回显 + 更新 |
GET /classes/{id} + PUT /classes |
2. 学员管理模块
功能 |
说明 |
方法示例(Rest 风格) |
学员列表 |
分页查询 + 按班级、姓名筛选 |
GET /students |
添加学员 |
支持文件头像上传 + 学员信息提交 |
POST /students |
删除学员 |
支持批量删除 |
DELETE /students?ids=... |
修改学员 |
查询 + 修改接口 |
GET /students/{id} + PUT |
违纪处理 |
标记违纪状态 / 添加记录 |
PATCH /students/{id}/discipline |
3. 数据统计模块
功能 |
SQL 技巧 |
接口返回值格式建议 |
班级人数统计 |
GROUP BY class_id |
List<Map<String,Object>> 或 VO对象 |
学员学历统计 |
GROUP BY education_level |
同上,支持生成柱状图 / 饼图数据结构 |
四、实战中可能遇到的问题 & 建议
问题类别 |
常见情况说明 |
建议解决方式 |
参数接收异常 |
@RequestParam 与 JSON 提交混用 |
搞清楚 GET 与 POST 的参数提交方式 |
日期格式错 |
前端传参与 Java 中 LocalDate 不匹配 |
使用 @DateTimeFormat(pattern=“yyyy-MM-dd”) |
事务未生效 |
多表操作时部分成功,部分失败 |
检查是否加了 @Transactional,是否异常被捕获 |
外键未处理 |
删除班级时无法删除学员 |
手动处理逻辑外键,或添加 ON DELETE 语句 |
接口文档偏差 |
实际接口返回值与文档不一致 |
严格按照接口文档定义入参与响应结构 |
五、小组演示建议内容
汇报模块 |
示例说明 |
功能实现说明 |
展示模块页面和接口测试,说明数据如何从前端流入数据库 |
思路与流程 |
简要画出流程图或讲解:控制层 → 业务层 → 数据层的调用顺序 |
Bug 经验总结 |
举出调试过程中遇到的典型问题,如空指针、SQL 错误、分页失效等 |
解决方案 |
简述通过日志排查、断点调试、API 文档核对等方式如何定位和修复 |
✅ 总结与建议
项目环节 |
初学者需要关注的重点 |
模块职责划分 |
理解控制层、服务层、Mapper 层的分工 |
接口规范 |
掌握 Restful 接口命名、请求方式、参数格式 |
数据一致性 |
掌握事务处理 @Transactional,注意回滚机制 |
实际操作能力 |
能从 0 到 1 实现接口设计、测试、调优、联调 |
团队沟通 |
锻炼文档协作、接口对接、问题复盘的沟通技巧 |
🧠 Day12 后端 Web 实战笔记:登录认证机制详解
一、登录功能实现
✅ 登录成功的本质是什么?
用户提供的用户名和密码,在数据库中存在并匹配。
✅ 核心流程
步骤 |
说明 |
请求参数接收 |
用户名、密码 |
查询数据库 |
根据用户名和密码查询 emp 表 |
判断是否存在 |
存在则登录成功,返回用户数据 + 令牌 |
登录失败处理 |
返回错误信息(如 401 未认证) |
SELECT * FROM emp WHERE username = ? AND password = ?;

二、登录校验(访问权限控制)
✅ 问题场景
未登录状态下仍可访问敏感接口,如 /emps、/depts,存在安全隐患。
✅ 目标:实现登录校验机制
功能 |
实现手段 |
登录成功后记录登录状态 |
使用“登录标记”如 Cookie、Session、Token 等 |
所有请求统一拦截、校验权限 |
使用 Filter(过滤器)或 Interceptor(拦截器) |

三、会话技术原理与对比
1. Cookie
- 客户端存储
- 由服务器响应
Set-Cookie
,客户端后续请求自动携带
缺点:
- 用户可禁用 Cookie
- 无法跨域
- 不安全(可伪造)
2. Session
- 服务器存储
- 基于 Cookie(JSESSIONID)识别用户
缺点:
- 集群部署时 Session 不共享,需额外配置共享机制(如 Redis)
3. Token(推荐)
在移动端与分布式系统中使用最广泛的会话跟踪方案
- 将登录状态数据编码成令牌,返回给客户端
- 客户端后续每次请求都携带该令牌
- 服务端验证令牌即可,无需保存状态,支持分布式
四、JWT 技术(Token 的主流实现)
✅ JWT(JSON Web Token)结构
JWT = Header + Payload + Signature
部分 |
内容说明 |
Header |
元信息:如签名算法 {"alg":"HS256","typ":"JWT"} |
Payload |
有效载荷,存放自定义信息,如 id 、username |
Signature |
签名,用于防篡改 |
✅ JWT 优点
- 支持跨端(PC/移动端)
- 减轻服务端压力
- 支持分布式架构(不依赖 Session)
✅ 使用流程
- 登录成功后,生成 JWT:
String token = Jwts.builder()
.setSubject("userInfo")
.claim("id", userId)
.claim("username", "Tom")
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
-
响应返回给前端,前端保存在 LocalStorage 或 Cookie 中
-
前端每次请求时在 Header 携带:
Authorization: Bearer <token>
- 服务端在过滤器/拦截器中校验 token:
Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
五、统一拦截机制
✅ 为什么需要统一拦截?
- 避免在每个接口中都写 token 校验逻辑
- 实现一次配置,处处生效
✅ Filter(过滤器)
特点 |
说明 |
属于 Java Web 规范 |
拦截所有资源请求(.jsp、.html、*.js) |
通用性强、适合登录认证、统一编码、日志记录等操作 |
|
Filter 开发流程
- 实现
javax.servlet.Filter
接口
- 实现
doFilter()
方法
- 使用
@WebFilter(urlPatterns="/*")
配置拦截范围
- 在启动类上加
@ServletComponentScan
开启扫描
✅ Interceptor(拦截器)
特点 |
说明 |
属于 Spring 规范 |
只拦截 Controller 请求(不拦截静态资源) |
控制更细粒度,适合权限控制、请求日志、请求时间统计等 |
|
Interceptor 开发流程
- 实现
HandlerInterceptor
接口
- 实现
preHandle()
方法(返回 true 放行,false 拦截)
- 实现配置类,重写
addInterceptors()
方法注册拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
}
✅ JWT 校验 Filter 流程图
请求到达 Filter
↓
判断是否是登录请求(/login) → 是:放行
↓
获取请求头中的 token → 没有:响应 401
↓
校验 token 合法性 → 非法或过期:响应 401
↓
放行请求
六、Filter 与 Interceptor 区别
对比点 |
Filter |
Interceptor |
所属规范 |
Java EE(Servlet) |
Spring MVC |
作用范围 |
所有请求,包括静态资源、第三方接口 |
Controller 控制器方法请求(更精细) |
执行顺序 |
先于 Interceptor 执行 |
Filter 执行完后才执行 Interceptor |
适合用途 |
登录校验、统一编码、跨域等 |
权限校验、日志、性能分析等 |
✅ 总结表
功能模块 |
学习重点 |
登录功能实现 |
接收用户名密码、数据库验证、返回 JWT |
会话技术对比 |
Cookie / Session / Token(三种方案优缺点 + 应用场景) |
JWT 使用 |
Header+Payload+Signature,掌握生成与校验方法 |
统一拦截机制 |
Filter 与 Interceptor 区别与使用流程 |
安全实践 |
登录校验流程设计、401 响应机制、token 续签(可拓展) |
🧠 Day13 后端 Web 进阶笔记:AOP(面向切面编程)
一、什么是 AOP?
- 全称:Aspect Oriented Programming(面向切面编程 / 面向方面编程)
- 定义:在不改变原始业务逻辑的前提下,将一些公共行为(如日志、权限校验、事务控制等)从业务代码中抽取出来统一管理。
✅ 场景示例
统计每个业务方法执行耗时:
- 在所有 service 方法中加时间统计?✘ 重复冗余
- 使用 AOP 统一处理?✅ 高效、解耦
✅ AOP 优势
优势 |
说明 |
减少重复代码 |
公共逻辑抽出,不需重复写 |
代码无侵入 |
原业务逻辑不需要修改 |
提高开发效率 |
共性功能一次配置,全局生效 |
易于维护 |
修改公共逻辑时,只需改一处即可 |
二、AOP 的核心概念(五大术语)
名称 |
含义说明 |
JoinPoint |
连接点:可以被 AOP 拦截的方法或执行点(如所有方法) |
PointCut |
切入点:实际要拦截的方法的定义规则(如 service.*) |
Advice |
通知:定义要执行的横切逻辑(如日志、权限) |
Aspect |
切面:通知 + 切入点的组合体 |
Target |
目标对象:被增强的原始业务类 |

三、AOP 快速入门实践(统计业务层方法执行耗时)
✅ 1. 引入 AOP 依赖(SpringBoot 默认已集成)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
✅ 2. 编写切面类
@Slf4j
@Aspect
@Component
public class TimeAspect {
@Around("execution(* com.xxx.service.impl.*.*(..))")
public Object recordExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long end = System.currentTimeMillis();
log.info("执行方法:{},耗时:{}ms", joinPoint.getSignature(), end - start);
return result;
}
}
四、通知类型详解(Advice)
通知注解 |
说明 |
@Around |
环绕通知,目标方法前后都能执行 ✅ 最常用 |
@Before |
前置通知,在目标方法执行前调用 |
@After |
后置通知,无论是否异常都会执行 |
@AfterReturning |
返回后通知,方法正常返回后执行(异常不会执行) |
@AfterThrowing |
异常通知,目标方法抛出异常时执行 |
✅ @PointCut 抽取公共切入点表达式
@Pointcut("execution(* com.xxx.service.impl.*.*(..))")
private void serviceMethods() {}
@Around("serviceMethods()")
public Object around(ProceedingJoinPoint jp) { ... }
五、切入点表达式详解
✅ execution 表达式语法
execution([修饰符] 返回值类型 包名.类名.方法名(参数) throws 异常)
✅ 通配符说明
通配符 |
含义 |
* |
匹配任意单个项(如返回值、类名等) |
… |
匹配任意层级包名 / 参数列表 |
✅ 常见示例
execution(* com.itheima.service.*.update*(..))
execution(* com.itheima..*.save(..))
✅ @annotation 表达式(通过注解匹配)
- 适用于无法通过方法签名表达的切面需求(如指定加了某个注解的方法)
@Around("@annotation(com.itheima.anno.Log)")
六、通知顺序控制(多个切面共存时)
- 默认顺序:按切面类名的字母顺序
- 推荐使用 @Order 注解:
@Order(1)
七、实战案例:记录增删改日志
✅ 日志需求
内容 |
说明 |
操作人 ID |
当前登录员工,从 JWT 令牌中获取 |
操作时间 |
当前系统时间 |
类名、方法名 |
通过 JoinPoint 获取 |
参数与返回值 |
JoinPoint 和 proceed() 获取 |
执行耗时 |
计算方法前后时间差 |
✅ 切入点表达式
@Around("execution(* com.itheima.controller.*.save(..)) || " +
"execution(* com.itheima.controller.*.update(..)) || " +
"execution(* com.itheima.controller.*.delete(..))")
或:
@Around("@annotation(com.itheima.anno.Log)")
八、ThreadLocal 用于传递登录用户信息
✅ 问题:如何从 JWT 中解析出的员工 ID 传给 AOP 程序?
✅ ThreadLocal 原理
- 是“线程内的全局变量”
- 每个线程有自己独立的变量副本,线程安全
✅ 用法示例
ThreadLocalUtils.set(currentUserId);
Long id = ThreadLocalUtils.get();
ThreadLocalUtils.remove();
✅ 应用流程
- 在 TokenFilter 中解析 JWT,得到登录员工 ID
- 将 ID 存入 ThreadLocal
- 在 AOP 或 Controller 中读取 ThreadLocal 获取登录用户信息
- 用完清除,避免内存泄漏
✅ 总结表
模块 |
核心内容与关键理解点 |
AOP 概念 |
统一处理共性问题的技术(如日志、安全、事务) |
核心术语 |
JoinPoint、PointCut、Advice、Aspect、Target |
通知类型 |
@Before、@After、@Around、@AfterReturning、@AfterThrowing |
表达式写法 |
execution、@annotation,支持通配符 * 和 … |
实战日志案例 |
使用环绕通知 + ThreadLocal + JWT 实现用户行为记录 |
🧠 后端开发进阶与总结笔记 day14(Maven + SpringBoot 原理 + 项目回顾)
一、Maven 高级用法详解
✅ 1. 分模块设计与开发
将大型项目按“模块”或“分层”拆分为多个子模块,提高可维护性与复用性。
拆分策略 |
举例 |
按功能模块 |
用户模块、商品模块、订单模块等 |
按系统层次 |
controller、service、mapper、pojo、utils |
功能 + 层次混合拆分 |
例如 mall-order-controller、mall-order-service |
📌 实战模块示例:
tlias-pojo
:实体类模块
tlias-utils
:工具类模块
tlias-service
:业务处理模块
✅ 2. Maven 继承与聚合
概念 |
说明 |
继承 |
子模块继承父工程的依赖、插件、属性(用于版本统一管理) |
聚合 |
父工程统一构建所有子模块(用于一次性打包整个项目) |
✍ 示例:
<parent>
<groupId>com.xxx</groupId>
<artifactId>tlias-parent</artifactId>
<version>1.0</version>
</parent>
<modules>
<module>tlias-pojo</module>
<module>tlias-service</module>
</modules>
💡 附加:版本锁定
- 在
<dependencyManagement>
中集中管理版本
- 子模块中无需写
<version>
✅ 3. 私服(Nexus)上传与使用
私服是团队共享 jar 包资源的仓库,上传依赖后局域网内即可复用。

上传步骤(3 部分配置):
- settings.xml 中配置私服账号
- pom.xml 中配置发布地址
<distributionManagement>
- 配置下载地址
<mirrors>
和 <profiles>
发布命令:
mvn clean deploy
二、SpringBoot 原理入门笔记
✅ 1. 配置优先级(从低到高)
application.yaml
(被忽略)
application.yml
application.properties
- Java 系统属性(-D 参数)
- 命令行参数(-- 参数)
💡 示例:
java -Dserver.port=9000 -jar xxx.jar --server.port=10010
✅ 2. Bean 管理方式对比
场景 |
推荐注解 |
管理自己写的类 |
@Component、@Service、@Controller 等 |
管理第三方类(外部 jar 包) |
@Bean 配合 @Configuration |
✅ 3. 起步依赖机制
所有 SpringBoot 的模块都以 spring-boot-starter-xxx
开头。
示例依赖 |
作用说明 |
spring-boot-starter-web |
web 模块(Tomcat) |
spring-boot-starter-data-jpa |
JPA 模块 |
spring-boot-starter-aop |
AOP 切面编程 |
💡 这些 starter 本质上是对依赖和配置的封装(起步依赖 + 自动配置)。
✅ 4. 自动配置原理深入理解
核心注解
@SpringBootApplication
等价于:
@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration
条件装配机制(@Conditional)
自动配置类并不是全都生效,而是由条件注解控制。
注解 |
含义 |
@ConditionalOnClass |
存在某个类才生效 |
@ConditionalOnMissingBean |
如果容器中没有该 Bean 才注册 |
@ConditionalOnProperty |
指定配置属性成立时生效 |
✅ 5. 自定义 Starter 步骤
场景:将通用工具类封装为自定义 starter,如:Aliyun OSS Starter
步骤:
- 创建
xxx-spring-boot-starter
模块
- 编写配置类 + 自动装配类
- 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
中声明自动配置类
- 引入 starter,自动注入即可使用!
三、Web 后端开发体系总结(知识图谱)
✅ 核心框架与技术栈
类型 |
技术 |
编程语言 |
Java |
框架体系 |
Spring、SpringBoot、MyBatis |
架构思想 |
三层架构(Controller、Service、Mapper) |
技术能力 |
AOP、IOC、DI、事务、异常处理 |
工具能力 |
Maven、JWT、OSS、Filter、Interceptor |
持久层工具 |
MyBatis、PageHelper |
安全能力 |
登录认证(JWT)、拦截器、会话管理 |
部署能力 |
打包 jar、私服发布、配置管理 |

✅ Web 开发常见组件梳理
类别 |
具体内容 |
数据模型 |
JavaBean、DTO、VO、PageBean |
通用模块 |
统一响应结构、统一异常处理 |
安全模块 |
登录认证(JWT)、权限控制 |
日志模块 |
AOP 实现操作日志记录 |
文件上传 |
本地存储 / 阿里云 OSS |
数据导出 |
Apache POI 实现 Excel 导出 |

✅ 开发流程总结
明确业务 → 数据库建模 → 接口设计 → 后端开发 → 前后端联调 → 部署上线
✅ 遇到问题建议先看控制台 → 查看日志栈信息 → 精确排查错误位置
✅ 总结图谱
Maven 高阶:
└─ 模块化设计
└─ 继承与聚合
└─ 私服上传配置
SpringBoot 原理:
└─ 配置优先级
└─ 起步依赖机制
└─ 自动配置(@EnableAutoConfiguration + @Conditional)
└─ 自定义 Starter
Web 技术总结:
└─ Controller / Service / Mapper 三层架构
└─ MyBatis、事务管理、统一异常处理
└─ JWT、拦截器、过滤器、AOP、OSS、日志
🧠 前端 Web day15 实战笔记(Vue 工程化 + Element Plus)
一、什么是 Vue?
✅ 特点
- 轻量、灵活、易学
- 基于数据驱动视图
- 支持组件化开发
- 拥有丰富生态(Vue Router、Pinia、Vite 等)
二、Vue 工程化开发
✅ 什么是前端工程化?
企业级开发中,对前端项目结构、规范、工具、流程的标准化、自动化管理方式。
工程化目标 |
说明 |
模块化 |
将项目划分为若干独立模块,职责单一 |
组件化 |
页面划分为组件,提高复用 |
规范化 |
统一目录结构、编码风格、开发流程 |
自动化 |
使用脚本自动构建、测试、部署等 |
✅ 环境准备
工具 |
作用 |
Node.js |
JavaScript 运行时,支撑 Vue 项目运行 |
npm |
Node.js 包管理器 |
create-vue |
Vue 官方脚手架,用于创建项目 |
npm create vue@3.3.4
npm install
npm run dev
访问地址:http://localhost:5173
✅ Vue 项目结构说明
文件 / 目录 |
作用说明 |
main.js |
项目入口文件 |
App.vue |
根组件 |
components/ |
通用组件目录 |
assets/ |
静态资源(图片、字体) |
package.json |
项目信息 + 所有依赖 + 脚本命令 |
vite.config.js |
项目配置(端口、代理等) |
✅ Vue 单文件组件(SFC)
Vue 推荐使用 .vue
文件来写组件:
将 HTML(结构)、CSS(样式)、JavaScript(逻辑)写在一个文件中,利于封装和复用。
<template>HTML结构</template>
<script>逻辑</script>
<style>样式</style>
三、Vue 的两种编程风格
风格 |
特点描述 |
选项式 API |
使用对象语法定义 data、methods、mounted 等 |
组合式 API |
使用函数组合逻辑,灵活、适合大型项目 ✅ 推荐 |
✅ 组合式 API 核心函数
函数名 |
用法说明 |
ref() |
定义响应式变量,访问时需 .value |
onMounted() |
生命周期钩子,页面加载后执行 |
setup() |
所有组合式 API 代码写在这里 |
setup() {
const count = ref(0);
onMounted(() => { console.log("页面已加载") });
return { count };
}
四、axios 异步请求(结合组合式 API)
✅ 安装
npm install axios
✅ 使用
import axios from 'axios';
onMounted(async () => {
const res = await axios.get('http://localhost:8080/api/users');
users.value = res.data.data;
});
五、Element Plus 简介
✅ 安装与引入
npm install element-plus@2.4.4 --save
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
六、Element Plus 常用组件使用
📊 表格组件 <el-table>
- 展示多条数据记录
- 必须绑定
:data="tableData"
<el-table :data="users" style="width: 100%">
<el-table-column prop="name" label="姓名"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
</el-table>
🔢 分页组件 <el-pagination>
-
用于大量数据的分页展示
-
常用属性:
:total
总记录数
:page-size
每页数量
@current-change
页码切换事件
💬 对话框组件 <el-dialog>
- 控制显示:
v-model="visible"
- 可嵌入表单、按钮等内容
<el-dialog title="提示" v-model="dialogVisible">
<span>确定删除该用户?</span>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="confirmDelete">确定</el-button>
</template>
</el-dialog>
📝 表单组件 <el-form>
- 表单项绑定值:
v-model
- 支持输入框、单选框、下拉框、多选框等
<el-form :model="form">
<el-form-item label="用户名">
<el-input v-model="form.username"></el-input>
</el-form-item>
</el-form>
七、实战案例要求(页面展示)
结合组合式 API + axios + ElementPlus,实现用户列表页:
要求 |
技术点 |
页面加载时获取用户数据 |
axios 异步请求 + onMounted |
渲染表格展示用户数据 |
el-table + el-table-column |
实现分页操作 |
el-pagination |
实现新增 / 修改 / 删除操作弹窗 |
el-dialog + 表单组件 |
✅ 总结回顾
内容板块 |
技能关键点 |
Vue 工程化 |
使用 create-vue 脚手架搭建项目,项目结构清晰 |
组合式 API |
学会使用 ref 、setup 、onMounted 等组合式函数 |
异步请求 |
使用 axios 发请求,处理响应数据 |
ElementPlus |
熟练掌握表格、分页、对话框、表单等组件使用方式 |
项目实践 |
将前后端数据结合,完成用户管理页面的展示与交互 |
🧠 前端 Web day16 实战笔记(Tlias 案例:部门管理模块)
一、项目背景介绍
✅ 项目名称
Tlias 智能学习辅助系统
✅ 本次开发模块
- 开发模式:前后端分离
- 当前前端模块:部门管理模块
- 后续可扩展:员工管理、班级管理、学员管理等
二、前后端分离开发模式
✅ 开发模式说明
特点 |
描述 |
前后端职责独立 |
后端提供接口,前端通过接口获取数据、渲染页面 |
并行开发 |
前后端可根据接口文档独立开发,提高效率 |
接口驱动开发 |
所有数据交互通过 HTTP 接口完成 |
✅ 前后端协作流程
需求分析 → 接口定义 → 并行开发 → 单元测试 → 联调测试
三、前端布局与 Vue 路由设计
✅ 页面布局组件(Element Plus)
组件标签 |
功能说明 |
<el-container> |
外部容器布局 |
<el-header> |
顶部导航栏 |
<el-aside> |
左侧菜单 |
<el-main> |
主内容区域 |
✅ Vue 路由核心组成
组件 / 对象 |
作用说明 |
router 实例 |
使用 createRouter 创建路由配置对象 |
<router-link> |
路由链接,最终渲染为 <a> 标签 |
<router-view> |
动态组件显示区域,页面切换时展示 |
<router-link to="/emp">员工管理</router-link>
<router-view></router-view>
四、部门管理模块实现步骤
📌 包括以下功能
功能 |
说明 |
查询列表 |
加载全部部门数据展示在表格中 |
新增部门 |
表单校验后提交新增数据 |
修改部门 |
回显 + 提交更新 |
删除部门 |
弹窗确认后执行删除 |
五、查询部门列表功能
✅ 页面布局组件
功能 |
Element 组件 |
操作按钮 |
<el-button> |
数据表格展示 |
<el-table> |
表格列 |
<el-table-column> |
✅ 数据加载流程
- 使用
onMounted()
生命周期钩子,在页面加载时调用数据加载函数
- 使用 axios 发送异步请求获取部门数据
- 将数据渲染到
<el-table>
中
✅ 接口调试优化建议
- 初期可使用 Mock.js 或 Apifox 提供的 Mock 服务
- 正式开发中建议封装请求逻辑:
六、新增部门功能
✅ 页面构成
功能 |
Element 组件 |
弹出窗口 |
<el-dialog> |
表单区域 |
<el-form> |
表单项 |
<el-form-item> + <el-input> |
校验规则 |
rules + prop + ref 组合使用 |
✅ 表单校验流程
- 定义校验规则:
rules: {
name: [{ required: true, message: '请输入部门名称', trigger: 'blur' }]
}
-
给表单绑定 rules
和 ref
,并调用 validate()
进行验证
-
校验通过 → 提交数据给后端 → 请求成功后刷新表格
七、修改部门功能
✅ 操作流程
步骤 |
说明 |
查询回显 |
点击“编辑”按钮 → 通过 ID 查询该条数据 |
展示弹窗 |
填充数据 → 弹出 <el-dialog> 表单 |
提交修改 |
提交后调用更新接口并刷新表格 |
八、删除部门功能
✅ 实现细节
- 点击“删除”按钮时,使用 ElementPlus 的弹窗组件进行确认:
ElMessageBox.confirm('确认删除该部门吗?', '提示')
.then(() => {
})
.catch(() => {
});
✅ 总结表格:Tlias 部门管理模块开发关键点
技术模块 |
学习关键 |
Vue 路由 |
使用 router-view + router-link 实现页面切换 |
axios 封装 |
使用 request.js + 模块 api 文件组织请求逻辑 |
页面布局 |
使用 ElementPlus 的布局容器实现导航 + 内容区域 |
数据加载 |
生命周期钩子 + 异步请求,填充表格数据 |
表单校验 |
ref + rules + validate 实现数据提交前检查 |
弹窗操作 |
dialog + messageBox 实现用户确认交互 |
🧠 前端 Web 实战笔记 day17(Tlias 案例 · 员工管理模块)
一、功能模块概览
本次开发目标是实现 “员工管理” 模块中的两个核心功能:
功能点 |
技术关键词 |
条件分页查询 |
表单绑定、表格渲染、分页组件、侦听器 |
新增员工 |
动态表单项、表单校验、异步提交 |
二、条件分页查询实现
✅ 页面组成
区块 |
说明 |
搜索栏(表单) |
绑定查询条件,如姓名、性别、入职日期 |
表格展示 |
用 <el-table> 渲染员工信息 |
分页条 |
用 <el-pagination> 切换页码 |
✅ 数据绑定建议
使用统一对象封装查询参数(推荐):
const searchEmp = reactive({
name: '',
gender: '',
date: ['2025-01-01', '2025-12-31']
})
在模板中使用 v-model 绑定:
<el-input v-model="searchEmp.name" />
<el-select v-model="searchEmp.gender">...</el-select>
<el-date-picker v-model="searchEmp.date" type="daterange" />
✅ 查询时机(页面交互逻辑)
触发场景 |
响应操作 |
页面加载后 |
自动发送请求加载第一页数据 |
点击“查询”按钮 |
重新查询 |
修改页码、页容量 |
自动重新发送请求 |
✅ 分页组件使用(Element Plus)
<el-pagination
:current-page="page"
:page-size="pageSize"
:total="total"
@current-change="handlePageChange"
@size-change="handleSizeChange" />
✅ Vue 组合式监听 watch()
侦听页码、页容量、查询条件变化,自动调用查询方法:
watch([page, pageSize], () => {
fetchEmployeeList()
})
三、新增员工功能实现
✅ 页面布局组成
部分 |
说明 |
弹出对话框 |
使用 <el-dialog> 展示表单 |
表单 |
使用 <el-form> 提交信息 |
工作经历 |
使用动态数组绑定多段工作经历信息 |
✅ 表单字段组成
- 基本信息(如用户名、性别、手机等)
- 工作经历(公司、开始时间、结束时间、职位等)
✅ 表单校验规则(示例)
const rules = {
username: [{ required: true, message: '用户名必填', min: 2, max: 20 }],
name: [{ required: true, message: '姓名必填', min: 2, max: 10 }],
gender: [{ required: true }],
phone: [{ required: true, pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确' }]
}
✅ 动态添加 / 删除工作经历项
const experiences = ref([
{ company: '', begin: '', end: '', job: '' }
])
const addExperience = () => {
experiences.value.push({ company: '', begin: '', end: '', job: '' })
}
const removeExperience = (index) => {
experiences.value.splice(index, 1)
}
页面中使用 v-for
渲染每段经历。
✅ 保存按钮逻辑
const submit = () => {
formRef.value.validate(async (valid) => {
if (valid) {
await axios.post('/api/emp', {
...formData,
experiences: experiences.value
})
dialogVisible.value = false
fetchEmployeeList()
}
})
}
四、watch() 侦听函数讲解
✅ watch 基础语法
watch(源, 回调函数, 可选配置)
参数 |
说明 |
源(第一个参数) |
可以是 ref、reactive、getter 函数 |
回调函数 |
数据变化后执行的逻辑 |
第三个参数 |
{ deep: true, immediate: true } 等 |
✅ 常用侦听方式
类型 |
写法 |
侦听单个属性 |
watch(() => user.value.name, callback) |
侦听多个属性 |
watch([page, pageSize], callback) |
深度侦听对象 |
watch(user, callback, { deep: true }) |
✅ 总结:员工管理模块重点复盘
项目 |
技术点 |
条件查询 |
表单封装查询条件、watch 自动联动、分页组件 |
表格展示 |
使用 el-table 显示员工信息,prop 精准绑定字段 |
动态表单 |
工作经历列表使用 v-for + ref 数组动态添加与移除 |
表单校验 |
rules + validate + pattern 结合使用 |
异步请求提交 |
axios 提交后判断响应,成功则关闭弹窗并刷新表格 |
🧠 Tlias 前端 Web 实战笔记 day18(终章:功能完善与部署)
一、员工管理模块:修改 & 删除
✅ 修改员工信息(两步)
-
点击“编辑”按钮
- 发送 axios 请求 → 根据员工 ID 查询详细信息
- 将返回数据填充到对话框的表单中(回显)
-
点击“保存”按钮
- 调用新增/修改接口(根据有无 id 判断)
- 表单验证通过后发送修改请求
if (form.id) {
} else {
}
✅ 删除员工信息
1. 删除单个员工
- 点击表格中某条记录右侧的“删除”按钮
- 弹出确认框 → 确认后发送删除请求(带 id)
2. 批量删除员工
- 用户勾选复选框选择多条记录
- 点击“批量删除”按钮,取出所有勾选的 id,封装为数组发送请求
const ids = selectedRows.map(item => item.id)
axios.post('/api/emp/deleteBatch', ids)
二、登录 & 退出功能完善
✅ 登录流程问题说明
当前问题 |
解决方案 |
登录成功未保存 Token |
使用 localStorage 保存 token |
每次请求需携带 Token |
设置 axios 请求拦截器统一处理 |
登录后访问页面未登录仍可访问 |
判断无 token 或 401 状态跳转登录页 |
✅ localStorage 基本用法
localStorage.setItem("token", res.data.token)
const token = localStorage.getItem("token")
localStorage.removeItem("token")
✅ 携带 Token 请求后端(拦截器)
👉 request 拦截器
axios.interceptors.request.use(config => {
const token = localStorage.getItem("token")
if (token) {
config.headers.Authorization = token
}
return config
})
👉 response 拦截器
axios.interceptors.response.use(
res => res,
err => {
if (err.response && err.response.status === 401) {
localStorage.removeItem("token")
router.push("/login")
}
return Promise.reject(err)
}
)
✅ 展示当前用户信息 + 退出登录
localStorage.clear()
router.push("/login")
三、前端项目打包与部署
✅ 打包操作(Vite 项目)
npm run build
- 会生成
dist
文件夹 → 里面是构建好的前端代码
✅ 使用 Nginx 部署
📦 第一步:复制 dist 内容到 Nginx
将 dist 文件夹内容复制到 nginx 安装目录中的 html 文件夹下
🚀 第二步:启动 Nginx
nginx.exe
nginx.exe -s stop
nginx.exe -s reload
🌐 第三步:访问项目页面
访问地址:http://localhost 或 http://127.0.0.1
默认使用 80 端口
✅ 知识总结总览
模块 |
技术点 |
员工信息修改 |
回显数据、表单复用、判断是否新增或修改 |
员工信息删除 |
单条 / 批量删除,使用确认框交互 |
登录认证优化 |
登录成功保存 token,axios 拦截器统一携带 token |
异常处理 |
401 统一跳转登录页,避免未登录访问受限资源 |
前端打包与部署 |
npm run build 构建、Nginx 服务器部署 dist 静态页面文件 |
这部分内容为整个前后端实战体系的收尾,是确保项目可以上线运行的关键步骤。
🧠 Day 19 项目部署笔记(基于 Linux 环境)
一、Linux 基础知识简介
✅ 什么是 Linux?
✅ 常见发行版
发行版 |
特点说明 |
CentOS |
企业常用,稳定(推荐学习使用) |
Ubuntu |
桌面系统友好 |
RedHat |
商业付费版 |
openSUSE |
图形界面丰富 |
Fedora |
新特性更新快 |
✅ 安装方式
安装方式 |
说明 |
物理机安装 |
安装在真实服务器硬件上 |
虚拟机安装 ✅ 推荐 |
使用 VirtualBox / VMWare 模拟环境 |
✅ 远程连接工具
- FinalShell ✅(推荐)
- XShell / Putty / SecureCRT 等
连接成功后,即可在 Windows 系统上远程操作 Linux。
✅ Linux 路径规则
/
:根目录,所有文件的起点
/home
:普通用户的家目录
/usr
:系统应用
/etc
:配置文件
/var
:日志、缓存
注意:
/itheima
是“根目录下的 itheima”
itheima
是“当前目录下的 itheima”
二、常用 Linux 命令速查
📁 目录/文件操作
目的 |
命令 |
查看内容 |
ls -al |
进入目录 |
cd /usr/local 、cd ~ |
创建目录 |
mkdir itcast 或 mkdir -p a/b |
删除文件/目录 |
rm -rf xxx |
📄 文件查看/编辑
工具 |
用途说明 |
cat |
一次性查看完整文件 |
more |
分页查看大文件 |
head |
查看文件前 n 行 |
tail -f |
实时查看文件末尾内容(如日志) |
vim |
编辑文件(命令模式 / 插入模式 / 退出) |
🔧 打包压缩
命令用途 |
示例 |
打包 |
tar -zcvf abc.tar.gz ./abc |
解压 |
tar -zxvf abc.tar.gz 或 -C /usr/local 解压到指定目录 |
📦 拷贝 / 移动
命令 |
示例 |
拷贝 |
cp hello.txt /home/user/ |
移动/重命名 |
mv hello.txt newname.txt 或 mv a.txt dir/ |
🔍 查找命令
- 按文件名找文件:
find . -name "*.log"
- 查文件内容:
grep "关键字" 文件名
三、常用环境安装(JDK、MySQL、Nginx)
✅ 安装 JDK(例如 JDK 17)
tar -zxvf jdk-17.0.10_linux-x64_bin.tar.gz -C /usr/local
vim /etc/profile
export JAVA_HOME=/usr/local/jdk-17.0.10
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile
java -version
✅ 安装 MySQL(8.0)
- 卸载系统默认的 mariadb
rpm -qa | grep mariadb
rpm -e --nodeps mariadb-libs-*
- 解压、移动、配置环境变量
tar -xvf mysql-xxx.tar.xz
mv mysql-xxx /usr/local/mysql
vim /etc/profile
export MYSQL_HOME=/usr/local/mysql
export PATH=$MYSQL_HOME/bin:$PATH
source /etc/profile
- 初始化数据库、启动服务
mysqld --initialize --user=mysql --basedir=... --datadir=...
systemctl start mysql
mysql -uroot -p临时密码
- 修改密码、远程授权
ALTER USER 'root'@'localhost' IDENTIFIED BY '1234';
CREATE USER 'root'@'%' IDENTIFIED BY '1234';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
FLUSH PRIVILEGES;
✅ 安装 Nginx
yum install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel
tar -zxvf nginx-1.20.2.tar.gz
cd nginx-1.20.2
./configure --prefix=/usr/local/nginx
make && make install
cd /usr/local/nginx
sbin/nginx
四、前后端项目部署流程(实战)
✅ 前端部署(Vue 项目)
- 打包:
npm run build
- 上传打包后的 dist 文件到 Linux:
- 配置 Nginx(反向代理):
location /api/ {
proxy_pass http://localhost:8080/;
rewrite ^/api/(.*)$ /$1 break;
}
- 重启 Nginx:
sbin/nginx -s reload
✅ 后端部署(SpringBoot 项目)
- 本地打包:
mvn clean package
- 上传 jar 包到服务器:
scp target/tlias.jar root@server:/usr/local/tlias-app/
- 后台启动服务:
cd /usr/local/tlias-app
nohup java -jar tlias.jar &> tlias.log &
- 查看日志 / 进程:
tail -f tlias.log
ps -ef | grep java
✅ 防火墙配置(可选)
操作 |
命令 |
关闭防火墙 |
systemctl stop firewalld |
永久关闭 |
systemctl disable firewalld |
开放端口 |
firewall-cmd --add-port=8080/tcp |
✅ 总结总览
模块 |
学习重点 |
Linux 基础 |
命令格式、路径规则、目录结构 |
常用命令 |
ls、cd、mkdir、rm、cp、vim、tar、grep、find |
软件环境 |
JDK、MySQL、Nginx 安装 + 配置 + 启动 |
项目部署 |
前端(Nginx)、后端(jar 包)、数据库连接配置 |
运维建议 |
使用 nohup 后台运行,定期检查日志 + 防火墙设置 |
🧠 Day20 Docker 学习笔记(初学者友好)
一、什么是 Docker?
- Docker 是一款用于快速构建、运行和管理应用的容器化工具。
- 目标:解决传统部署中“依赖难装、环境难配、迁移困难”等问题。
二、Docker 核心概念
概念 |
说明 |
镜像 (Image) |
应用+环境的打包模板,如 MySQL 镜像、Java 镜像 |
容器 (Container) |
镜像运行时的实例,是一个独立的轻量级运行环境 |
镜像仓库 |
用于存储镜像的服务,如 DockerHub |
Dockerfile |
构建镜像的脚本文件,用于定义应用环境与启动方式 |
三、Docker 快速入门实战
✅ 安装 MySQL(镜像方式)
docker run -d \
--name mysql \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=123 \
mysql:8
说明:
参数 |
含义 |
-d |
后台运行容器 |
–name |
指定容器名称 |
-p |
宿主机端口:容器端口 |
-e |
设置环境变量,如 root 密码 |
四、镜像与容器常用命令
📦 镜像操作
docker pull mysql
docker images
docker rmi 镜像名
📦 容器操作
docker run
docker ps
docker stop 容器ID
docker start 容器ID
docker rm 容器ID
docker logs 容器ID
docker exec -it 容器ID bash
五、数据卷(Volume)机制
数据卷用于实现容器与宿主机之间的数据持久化与共享。
✅ 两种挂载方式
挂载方式 |
命令示例说明 |
命名卷 |
-v mysql:/var/lib/mysql |
本地目录挂载 ✅ 推荐 |
-v /root/mysql:/var/lib/mysql |
✅ 数据卷操作命令
docker volume ls
docker volume inspect 名称
docker volume rm 名称
六、自定义镜像(Dockerfile)
✅ Dockerfile 常见指令
指令 |
用途 |
FROM |
指定基础镜像(如 centos) |
COPY |
拷贝文件到镜像内 |
RUN |
构建时执行的命令 |
ENV |
设置环境变量 |
EXPOSE |
暴露端口 |
ENTRYPOINT |
启动镜像时执行的命令 |
✅ 构建命令
docker build -t my-java-app .
七、Docker 网络通信
✅ 网络模式
模式 |
特点说明 |
bridge ✅ |
默认模式,所有容器连到 docker0 网桥 |
host |
容器与宿主机共享网络 |
none |
容器没有网络 |
自定义网络 |
允许容器通过名字互相访问,适用于服务间通信 |
docker network create my-net
docker run --network my-net --name mysql ...
docker run --network my-net --name app ...
八、Docker Compose 快速部署
使用 docker-compose.yml 管理多容器协同部署(如前端、后端、数据库)
✅ 项目结构准备
docker-compose.yml
tlias-server/
├── Dockerfile
├── tlias.jar
├── jdk17/
tlias-nginx/
├── html/
├── nginx.conf
✅ docker-compose.yml 示例
version: "3.8"
services:
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: 123
ports:
- "3306:3306"
backend:
build: ./tlias-server
ports:
- "8080:8080"
depends_on:
- mysql
frontend:
image: nginx
volumes:
- ./tlias-nginx/html:/usr/share/nginx/html
- ./tlias-nginx/nginx.conf:/etc/nginx/nginx.conf
ports:
- "80:80"
✅ 启动命令
docker compose up -d
docker compose down
九、Tlias 项目部署实操总结
✅ 服务端
- 修改
application.yml
:数据库地址为 mysql 容器名
- 编写 Dockerfile,配置 JDK、JAR 包
- 构建镜像,运行容器或使用 Compose 自动部署
✅ 前端
- 使用 Nginx 镜像部署静态文件
- 配置 nginx.conf,实现前后端联通(/api 转发)
✅ 知识图谱总结
Docker 入门:
├─ 镜像 & 容器
├─ docker run 参数详解
├─ 数据卷(持久化)
├─ 网络模式(通信)
└─ Dockerfile(构建镜像)
Docker 进阶:
├─ docker-compose 多容器部署
├─ Tlias 项目服务端镜像构建
└─ Nginx 容器部署前端资源
所有评论(0)