learning-demo 项目解读 - 用大白话讲清楚一个全栈项目

星期四, 4月 9, 2026 | 3分钟阅读 | 更新于 星期四, 4月 9, 2026

@

这个项目是干嘛的?

一句话:一个用户管理系统。能注册用户、查看用户列表、编辑用户信息、删除用户、禁用/启用用户。

就跟你注册一个网站账号一样简单的事,但这个项目把背后的每一步都拆开来讲了。


项目长什么样?

项目分两个大文件夹:

learning-demo/
├── backend/    ← 后端(Java / Spring Boot)
└── frontend/   ← 前端(Vue 3)
  • 后端:负责处理数据、存数据库、管缓存
  • 前端:负责显示页面、让用户点点点

它们之间通过 HTTP 接口(API)来沟通。


用一个比喻讲清楚整个架构

想象一家餐厅:

角色对应的技术干啥的
顾客前端(Vue 3 页面)看菜单、点菜
服务员HTTP 接口(API)把顾客的订单传到后厨
后厨后端(Spring Boot)处理订单、做菜
冰箱数据库(MySQL)存食材(数据)
备菜台缓存(Redis)常用的东西放身边,拿得快
传菜窗口消息队列(Kafka)后厨做好菜,放到窗口,服务员来取

后端是怎么组织的?

后端代码按职责分层,每一层只干自己的事:

com.demo/
├── controller/     ← 接单员:接收前端请求
├── service/        ← 大厨:处理业务逻辑
├── mapper/         ← 仓库管理员:操作数据库
├── entity/         ← 食材清单:数据库表的映射
├── dto/            ← 外卖盒:返回给前端的数据包装
├── config/         ← 厨房设备配置
├── kafka/          ← 传菜窗口:发送和接收消息
├── redis/          ← 备菜台:缓存操作
└── common/         ← 公用工具:统一返回格式

用户注册的完整流程

当前端发来一个注册请求时,数据是这样走的:

前端页面
  ↓ 用户点击"注册"
API 请求(POST /api/users/register)
  ↓
Controller(UserController.java)
  ↓ 接收请求,校验参数
Service(UserServiceImpl.java)
  ↓ 1. 检查用户名是否重复
  ↓ 2. 密码加密
  ↓ 3. 存入数据库
Mapper(UserMapper.java)
  ↓ 执行 SQL
MySQL 数据库
  ↓ 存好了
  ↓ 4. 发一条消息到 Kafka("嘿,有新用户注册了!")
  ↓ 5. 把用户信息存到 Redis 缓存(下次查得快)
  ↓
返回结果给前端

每一层干了什么?

Controller(接单员) - UserController.java

只负责接活。前端说"我要注册",它就把活派给 Service。

@PostMapping("/register")
public Result<UserDTO> register(@RequestBody RegisterRequest request) {
    UserDTO user = userService.register(request);
    return Result.success(user);
}

大白话:有人来注册,我把表单交给 userService 去处理,处理完了把结果包好返回。

Service(大厨) - UserServiceImpl.java

这是核心逻辑。注册一个用户,要干这些事:

  1. 检查用户名是不是已经有人用了
  2. 把密码加密(不能明文存)
  3. 存到数据库
  4. 发一条 Kafka 消息(通知其他服务有新用户了)
  5. 把用户信息缓存到 Redis

Mapper(仓库管理员) - UserMapper.java

直接操作数据库。用的是 MyBatis-Plus,它能帮你自动生成常用的 SQL,不用自己写:

public interface UserMapper extends BaseMapper<User> {
    // 继承 BaseMapper 后,selectById、insert、deleteById 这些方法自动有了
    // 只有特殊的查询才需要自己写
}

配置类(厨房设备)

文件作用
RedisConfig.java配置 Redis 连接,告诉程序缓存服务器在哪
KafkaConfig.java配置 Kafka,告诉程序消息队列在哪
WebConfig.java配置跨域(允许前端访问后端)

数据相关的类

Entity(数据库表映射) - User.java

对应数据库里的一张 user 表:

user 表
├── id          ← 用户ID,自动生成
├── username    ← 用户名
├── password    ← 加密后的密码
├── email       ← 邮箱
├── status      ← 状态(1=正常,0=禁用)
└── created_at  ← 创建时间

DTO(数据传输对象) - UserDTO.javaRegisterRequest.java

  • RegisterRequest:前端传过来的注册表单(用户名、密码、邮箱)
  • UserDTO:返回给前端的用户信息(注意:不包含密码

为什么不直接用 Entity?因为 Entity 里有密码,返回给前端不安全。DTO 就是"过滤后的版本"。

Redis 缓存是干嘛的?

每次查数据库都要走网络、读磁盘,很慢。Redis 把常用的数据放在内存里,下次查的时候先看 Redis 有没有,有就直接返回,快很多。

查询用户 → 先查 Redis 缓存
              ├── 有 → 直接返回(快!)
              └── 没有 → 查数据库 → 存到 Redis → 返回

Kafka 是干嘛的?

Kafka 是个消息队列。就像微信群消息:有人发了消息,感兴趣的人可以自己去看。

这个项目里,用户注册成功后,后端会发一条 Kafka 消息:"新用户注册了!用户名是 xxx"UserKafkaConsumer 收到消息后,会打印一条日志。实际项目中,可以用来做"发欢迎邮件"、“初始化用户配置"等。


前端是怎么组织的?

frontend/src/
├── main.js              ← 入口文件:创建 Vue 应用
├── App.vue              ← 根组件:页面的大框架
├── api/
│   └── user.js          ← API 封装:所有和后端通信的函数
├── stores/
│   └── user.js          ← 状态管理:存全局数据
├── views/
│   └── UserManage.vue   ← 页面:用户管理的整个页面
└── components/
    └── UserForm.vue     ← 组件:新增/编辑用户的表单

前端的核心概念(三句话版)

  1. Vue 组件:每个 .vue 文件就是一个组件,包含 HTML 模板 + JS 逻辑 + CSS 样式
  2. Pinia Store:全局的数据仓库。比如用户列表,存在 store 里,任何组件都能用
  3. API 层:把所有"跟后端要数据"的代码放在 api/user.js 里,别的组件调用就行

前端请求流程

用户点击"注册"
  ↓
UserForm.vue 调用 store.register(data)
  ↓
stores/user.js 调用 userApi.register(data)
  ↓
api/user.js 用 axios 发送 POST /api/users/register
  ↓
后端处理,返回结果
  ↓
store 更新 userList(页面自动刷新)

跨域问题怎么解决的?

前端跑在 localhost:5173,后端跑在 localhost:8080,浏览器会阻止跨域请求。

解决办法在 vite.config.js 里:

proxy: {
  '/api': {
    target: 'http://localhost:8080',
    changeOrigin: true
  }
}

意思是:前端请求 /api/users/register,Vite 帮你转发到 http://localhost:8080/api/users/register


数据库表结构

就一张表:

CREATE TABLE user (
    id          BIGINT AUTO_INCREMENT PRIMARY KEY,  -- 用户ID
    username    VARCHAR(50)  NOT NULL UNIQUE,       -- 用户名(不能重复)
    password    VARCHAR(100) NOT NULL,              -- 密码(加密存储)
    email       VARCHAR(100),                       -- 邮箱
    status      INT DEFAULT 1,                      -- 状态:1正常,0禁用
    created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间
);

API 接口一览

方法路径干啥
POST/api/users/register注册新用户
GET/api/users?page=1&pageSize=10获取用户列表(分页)
GET/api/users/all获取所有用户
GET/api/users/{id}根据ID查用户
GET/api/users/username/{name}根据用户名查
PUT/api/users/{id}更新用户信息
PUT/api/users/{id}/status?status=0更新用户状态
DELETE/api/users/{id}删除用户
GET/api/users/stats获取统计信息
GET/api/users/cache/stats获取缓存统计

学到了什么?

这个项目虽然简单,但涵盖了全栈开发的核心知识:

知识点这个项目怎么用的
分层架构Controller → Service → Mapper,各干各的
DTO 模式返回给前端的数据和数据库表不一样,保护敏感信息
缓存Redis 做缓存,查得快
消息队列Kafka 异步通知,解耦服务
跨域处理Vite 代理转发
状态管理Pinia 管理前端全局数据
表单验证前端 Element Plus 验证 + 后端参数校验

把这个项目搞明白了,全栈开发的基本套路就入门了。

© 2026 My Blog

🌱 Powered by Hugo with theme Dream.