☰
Spring Boot + Vue + MySQL手搓管理系统:从0到部署全攻略
2026/10/1 3:26:16 网站建设 项目流程

“手搓”这个词说出来,就带着一股自己动手的底气。十年前做管理系统,你得从Servlet和JSP开始啃,配一堆web.xml和繁琐的配置文件;现在你只需要Spring Boot负责后端接口、Vue负责页面渲染、MySQL负责数据落地,三样东西各管一摊,一个人就能把一个后台管理系统从零写到能上线。这篇文章就是一份完整的手搓记录——从数据库设计、后端接口、前端页面到最后的部署,把每一步怎么走、坑在哪里、为什么这么选,全都摊开说清楚。不管你是在校学生准备做毕业设计,还是公司里需要快速搭一个内部管理后台,这条路子都值得参考。

1. 为什么敢选Spring Boot+Vue+MySQL这个组合

1.1 技术栈选择的底层逻辑

Spring Boot + Vue + MySQL这个组合,在Java开发圈子里几乎成了“管理系统”的标准答案。为什么?我从三个角度拆给你看。

后端选Spring Boot,核心原因是生态太成熟了。Spring Boot内置Tomcat,提供自动配置和Starter机制,你只需要写一个main方法,就能把一个Web服务启动起来。相比早年SSH(Spring + Struts + Hibernate)那一代框架的繁琐配置,Spring Boot把大量XML配置砍掉了。最难得的是它的社区资源极其丰富,几乎所有你能想到的功能——文件存储、消息队列、定时任务、短信通知——都有现成的Starter可以直接引入,不需要自己造轮子。

前端选Vue,最实在的优点就是上手曲线平缓。做一个管理后台,Vue 2或Vue 3配合Element Plus组件库,你只需要掌握几个核心概念:数据绑定、组件化、路由、状态管理,这套东西就能玩转绝大多数中后台场景。Vue的组件生态对中后台项目特别友好,表格、表单、弹窗、分页这些高度重复的页面结构,通过组件封装可以做到非常高的复用率。

数据库选MySQL,这个更不用多说。免费、稳定、普及率高,很多公司的业务系统都在用它。配合可视化客户端工具,建表、调试SQL、导出数据,新手也能很快上手。虽然现在国际上也有PostgreSQL这样的强手在冲击,但在国内,Java生态和MySQL的配合一致性还是最强的。

这三个凑在一起,真正的价值是什么?是资料密度。你遇到任何一个问题,搜索一下基本都有前人踩过的坑和现成的解决方案。这一点在实战里比技术本身的先进性重要得多。孤军奋战的时候,能搜到答案比什么都强。

1.2 系统模块设计与权限模型

手搓管理系统,第一步不是写代码,而是先想清楚“这个系统到底要管什么”。哪怕是最精简的后台,你也应该拆出这么几个模块:

  • 登录认证:用户的登录、退出、会话状态管理
  • 用户管理:用户的增删改查、状态启用与禁用
  • 角色管理:角色的创建,以及角色和权限的绑定关系
  • 菜单管理:前端路由对应的菜单项,以及按钮级别的权限控制
  • 核心业务模块:比如员工管理、订单管理、内容发布等实际业务

把这份清单列出来,你发现一个管理系统的骨架就已经成型了。这里的核心设计模式是RBAC(基于角色的访问控制)。如果不做权限模型,一张用户表加一张业务表也能跑起来,但一旦系统里有多个人在用,问题就来了:谁能删数据?谁能看到某个菜单?谁只能录入不能修改?这些全靠“自觉”是行不通的。

所以,真正可用的管理系统必须解决“谁能做什么”的问题。RBAC模型是标配:用户属于某个角色,角色绑定一批权限,权限对应菜单和按钮操作。这套模型一上,整个系统的扩展性就打开了。后面加新模块,无非是往菜单表里加记录、往角色权限表里加绑定,完全不需要动用户表的逻辑,这就是权限模型带来的长期红利。

2. 环境准备的三件套,一个都不能少

2.1 JDK与Maven:后端地基

后端开发的第一步是装好Java环境。需要注意一个版本选择问题:Spring Boot 3.x要求JDK 17起步,而你如果用的是Spring Boot 2.7.x,JDK 8就够了。我建议如果你是从零开始,直接上JDK 17加Spring Boot 3.x,没必要逆着时代走。当然,如果你之后要接手老旧项目,再把JDK版本降回去也不迟。

装完JDK,还需要Maven来管理项目依赖。Maven的核心作用是帮你自动下载Spring Boot的各种依赖包,同时负责整个项目的编译和打包。你不需要掌握太多Maven知识,但至少要清楚settings.xml里的阿里云镜像仓库是需要配置的,不然下载依赖会让你怀疑人生。我试过默认配置下,一个简单项目光下载依赖就能花一两个小时,换成国内镜像之后,几分钟就完事。

后端开发工具,我建议用IntelliJ IDEA。社区版免费就够用,Professional版本可以支持Spring Boot的专门创建向导,不过即便没有,你也可以直接从start.spring.io网页端生成项目再导入IDEA,效果一样。

2.2 Node.js与Vue脚手架:前端基础

前端环境相对简单,核心是安装Node.js。Node.js自带npm包管理工具,npm或cnpm负责下载JavaScript依赖。这里有个常见的坑:Node版本太高,安装老旧的vue-cli脚手架会报各种奇怪的兼容性错误。所以建议遵循官方当前推荐路径——直接用Vite方式创建Vue 3项目,命令是npm create vue@latest。新项目用Vite是现在最顺的手感,它启动速度快,热更新快,开发体验比Webpack时代的vue-cli舒服太多。

开发工具我用的是VSCode,配合Vetur或Volar插件做Vue语法高亮。编辑器顺手之后,前端开发效率会高不少。

有朋友问过:Electron打包vue项目和这个有关系吗?那是桌面应用场景,你如果只想做浏览器里跑的管理后台,完全不用管Electron那套主进程、渲染进程的复杂性,先把本分做好,桌面端以后真有需求再说。

2.3 MySQL安装与客户端选择

MySQL安装要注意版本。Windows下推荐安装MySQL 8.0.x,官方安装包安装过程不难,但有两个点必须留意:一是设置root密码之后要记住,二是选择认证方式时,如果客户端工具比较老,需要选择兼容模式,防止出现加密协议不匹配导致连不上。

安装完成后,用命令行测试mysql -uroot -p能正常进入,说明服务已经起来了。日常操作数据库,我习惯用Navicat,它虽然是个付费软件,但确实太好用了。免费替代品有DBeaver,功能也很全面,只是界面风格偏硬核一些。

客户端工具解决的是看得见的问题:建表、看数据、改字段、跑SQL,都有图形界面,不用在命令行里黑灯瞎火地敲。新手阶段这个体验差距非常大。

3. 数据库设计,管理系统的地基不能马虎

3.1 核心表结构与RBAC权限模型落地

数据库设计是整个项目里最不能省时间的部分。表结构设计好了,后续写代码就是水到渠成。我这里给出一个经过实战检验的最小权限模型,一共三张核心表加四张辅助表。

用户表(sys_user)是最基础的,字段至少要包含id、用户名、密码、昵称、头像、邮箱、状态、创建时间。用户名要求唯一,状态字段用0表示禁用、1表示启用,这是一个低调但非常实用的设计,禁用功能在后台管理里极其常用。

角色表(sys_role)字段相对简单:id、角色名称、角色编码、描述、状态。角色编码在代码里做逻辑判断时用,不要用中文做判断条件,这个习惯很重要。

菜单表(sys_menu)承担了权限的具体内容:id、菜单名称、菜单类型(目录/菜单/按钮)、路由地址、组件路径、权限标识、父级ID、排序号。这里菜单类型的区分要特别注意,目录是顶层分类,菜单是可点击的页面,按钮是页面里的具体操作权限——增删改查都可以通过按钮权限精细控制。

除了这三张主表,还有三张关联表:用户-角色关联表(sys_user_role)、角色-菜单关联表(sys_role_menu)。为什么要把关联单独拆出来?因为用户和角色是多对多关系,一个用户可以有多个角色,一个角色也能赋给多个用户。如果把关联塞进用户表,字段就会出现冗余,将来扩展也会很痛。

3.2 字段规范与建表实操心得

建表的时候,我强烈建议你遵守几个约定俗成的规范。首先,每张表都要有id主键,类型用bigint还是int取决于你的数据量预期,中小系统int够用。其次,每张表最好都带上create_time、update_time、deleted这三个字段。create_time和update_time在后续列表排序、排查数据问题时非常好用,deleted字段是实现逻辑删除的关键——注意别真的把记录从数据库里删掉,而是用deleted标记,这对保留历史操作记录非常重要。

关于表名和字段名,全用下划线小写风格,比如sys_user、create_time。Java后端里的驼峰命名和数据库下划线命名之间的转换,交给MyBatis-Plus的自动驼峰映射功能处理就行。我见过有项目建表时字段直接用驼峰,虽然也能跑,但看起来非常不专业,而且在写原生SQL时反而容易出错。

还有一个容易踩的坑:MySQL里不要用user做表名,虽然MySQL帮我们做了兼容处理,但为了保险起见,用sys_user或者t_user这种带前缀的表名更稳妥,因为user在不少数据库系统里是保留字。

4. 后端接口开发,Spring Boot从零到能跑

4.1 快速初始化与依赖配置

我在实际开发中通常直接去start.spring.io生成基础工程。页面左侧选择Maven工程、Java语言、Spring Boot版本,右侧填写groupId和artifactId,再勾选需要的依赖。最基础的依赖组合是:Spring Web、MySQL Driver。如果你确定要使用MyBatis,还可以勾选MyBatis Framework,不过我个人习惯先把项目生成出来,再手动引入依赖,这样更可控。

生成的工程解压后用IDEA导入,结构非常清晰:Application类负责启动,resources目录下放着配置文件。接下来在pom.xml里手动补上几个关键依赖:MyBatis-Plus、JWT工具库(比如jjwt)、Lombok。MyBatis-Plus是我强烈推荐的持久层框架,它不是让你放弃写SQL,而是把单表CRUD的模板代码从你的日常中删掉。你只需要在Mapper接口中声明继承BaseMapper,连基本的增删改查SQL都替你生成了,接下来专注写业务逻辑就好。至于JWT,用于登录认证,后面细说。

配置application.yml有两种选择:application.properties或application.yml。我个人更倾向.yml格式,因为层级清晰,不容易出现大段重复前缀。核心配置点有两个:一是数据源信息,包括URL、用户名、密码;二是MyBatis-Plus相关配置,比如mapper-locations、逻辑删除配置、主键生成策略等。数据源URL里让你踩坑最多的地方我放到后面的问题排查章节里说,这里先把代码跑通。

4.2 三层架构与CRUD接口的落地细节

后端代码的典型分层是Controller → Service → Mapper。Controller层只负责接收前端请求、调用Service并返回结果;Service层封装业务逻辑;Mapper层处理数据库交互。这个分层看着简单,但它是整个后端工程后期可维护性的保障。如果你把SQL都堆在Controller里,前三个月确实很爽,三个月之后你就会开始吃苦头。

我以一个用户管理模块为例说明具体的实现套路。先创建一个User实体类,字段对应数据库表列,给类加上Lombok的@Data注解,省去手写getter/setter。创建UserMapper接口,继承BaseMapper ,什么都不用写,CRUD方法就全有了。创建UserService接口和实现类,在实现类里调用Mapper方法,实现分页查询、条件过滤、新增、修改、删除的逻辑。最后写UserController,用@RestController注解,定义RESTful风格的接口路径,比如/api/user/list、/api/user/add。

分页查询这里特别值得单独说明。MyBatis-Plus提供了分页插件,你需要先注册一个配置类,添加MybatisPlusInterceptor和PaginationInnerInterceptor。配置完成之后,分页查询就可以直接调用Page对象。前端传页码和每页数量,后端返回总记录数和当前页数据。分页查询返回的数据结构建议统一封装一下,我习惯封装成Result对象,包含code、message、data三个字段,这样前端处理起来会很统一,不用每隔接口单独处理异常情况。

4.3 JWT登录认证的实现思路

管理系统最重要的一环就是登录。我把登录认证的设计思路拆解一下。

用户提交用户名和密码,后端先在user表里查记录,密码需要加密存储,不能明文落库。密码加密推荐用BCrypt算法,Spring Security框架里就内置了这个工具类,如果你不想整套引入Spring Security,可以单独引入jBCrypt库,也能实现同样的效果。BCrypt的特点是每次生成的hash都不一样,但校验结果一致,而且自带盐值处理,安全性比MD5高出很多。

登录成功之后,后端生成一个JWT令牌返回给前端。JWT包含用户的id、用户名、过期时间等少量信息,通过服务端密钥进行签名,防篡改。前端拿到token后存储在localStorage或pinia状态里,后续每次请求都在HTTP请求头里带上Authorization: Bearer 。

后端怎么验证这个token?我习惯用HandlerInterceptor,也就是Spring MVC提供的拦截器机制。写一个拦截器类,实现preHandle方法:从请求头里取出token,解析并校验签名,校验通过就放行,失败就返回401状态码。然后注册到配置类里,只需要排除登录接口和静态资源路径,其余接口全部拦截。这套实现下来,登录认证的核心链路就通了。

5. 前端页面,Vue从Hello World到管理后台

5.1 初始化Vue 3项目并集成Element Plus

前端工程初始化用Vite是最顺手的。执行npm create vue@latest,根据提示选择TypeScript、Vue Router、Pinia这些选项。这里我建议:如果你对TypeScript还不熟,哪怕项目规模小,也建议从TS起步,因为Vue 3对TS的支持已经很完善了,后面维护起来确实省心。不过你要是急着毕业设计出活,直接JavaScript也可以,没必要和自己较劲。

项目创建完成后,安装Element Plus组件库是下一步。Element Plus是Vue 3时代的组件库,提供按钮、表格、表单、弹窗、分页、菜单等一套完整的中后台组件。它最大的价值是让一个完全没有设计能力的人也能做出看起来像模像样的后台界面。安装命令很简单:npm install element-plus。考虑到组件库按需引入配置起来需要额外步骤,新手阶段可以直接全量引入,反正本地开发阶段没人关心包体积,先跑起来再说。

顺便提一个细节,Element Plus自身是支持国际化的,默认是英文文案,你要在main.js里配置中文语言包,不然分页组件和日期组件里全是英文,看着很违和。

5.2 请求封装与登录联调

前端和后端的数据交互,我用axios完成。官网推荐用fetch的库也有不少,但axios的生态成熟度最高,拦截器机制也非常好用。使用时,我会在src/utils目录下创建一个request.js文件,先生成一个axios实例,设置baseURL、超时时间。然后用axios拦截器做两件事:请求拦截器里,从localStorage读取token,加上Authorization请求头;响应拦截器里,如果后端返回401,就清理本地登录状态并跳转到登录页。

封装好基础的请求工具之后,写登录页逻辑就非常顺了。调用/api/login接口,把用户名和密码提交给后端,拿到token后存起来,再跳转到首页。这里需要处理的边界情况是:账号密码错误,后端返回的code不等于200,前端要弹出提示;网络错误,axios进入catch分支,也要给用户明确反馈。这些细节看起来不起眼,但却是管理系统真正的体验分水岭。

5.3 路由守卫与页面权限控制

前端页面的权限控制,我建议分成两层。第一层是路由守卫。在router.js文件里,给需要登录才能访问的路由加上meta: { requiresAuth: true }标记。Vue Router提供了全局前置守卫,每次跳转之前判断:如果目标路由需要认证,且本地没有token,就强制跳转到登录页。这样刷新页面时用户的登录态会被保留,未登录用户也进不了系统内部。

第二层是菜单权限。登录成功之后,调用后端接口获取当前用户的菜单列表和按钮权限标识,动态生成侧边栏菜单,并且在前端按钮上通过指令或权限方法控制显示隐藏。这一步完整的实现方式可以做得比较深,但对一般管理系统来说,至少要把动态菜单做出来:菜单数据存在Pinia状态里,侧边栏组件根据数据渲染,用户没权限的菜单不显示。而按钮级别的指令权限,等系统真的复杂到需要再上也不迟,动手项目不必一步到位。

6. 联调与排查,实战中最容易踩的坑

6.1 跨域问题与解决思路

前后端分离开发模式一上线,遇到的第一个拦路虎绝对是跨域。前端页面跑在localhost:5173,后端接口跑在localhost:8080,浏览器的同源策略直接把你的请求拦在半路,报Access-Control-Allow-Origin错误。

解决跨域常见有两种思路。第一种是后端开启CORS。在Spring Boot里通过配置类实现WebMvcConfigurer,重写addCorsMappings方法,允许跨域来源、方法和请求头。这种方案的优点是接口谁都能调,但生产环境如果前后端部署在同一个Nginx域名下,其实就不需要跨域了,所以更适合开发环境。

第二种思路是前端开发时配置代理。Vite配置proxy,把请求后端接口的路径代理到真实地址,让浏览器看到的是同源页面,跨域问题自然消失。这是开发环境我更推荐的方案,部署的时候,Nginx同样可以配置代理转发,逻辑完全一致。要注意的是,生产环境里跨域配置要谨慎,不要用通配符*,而是明确指定允许的域名,这个细节涉及安全问题。

6.2 MySQL连接异常专坑指南

MySQL连接出问题,几乎是每一个新手必撞的墙,我这里把你可能遇到的情况提前讲明白。

最经典的是Communications link failure这个报错。这往往意味着应用根本连不上数据库。排查顺序应该是:数据库服务有没有启动,3306端口有没有被占用,用户名密码是否正确,以及后端配置的URL是否写对。有时看似复杂,一查发现只是MySQL服务忘了启动,这种事我见过太多次了。

第二个常见问题是SSL连接错误。MySQL 8.0默认开启SSL加密,但本地开发时我们一般不需要。解决方法是在数据源URL上直接追加参数useSSL=false和serverTimezone=Asia/Shanghai。顺带提一下,时区参数也很重要,不设置的话,数据库时间和Java时间可能会出现八小时的偏移,别问我是怎么知道的。

第三个问题是mysql.sock或用户名密码被拒,多半是密码配置前后端不一致。还有人会碰到Access denied for user,那就要去MySQL里重新授权或者重置密码。遇到报错先别慌,把报错信息完整贴到搜索框里,一般都能找到答案。

6.3 版本兼容问题速查表

版本兼容问题是我在项目里感受最深的一个坑。Spring Boot 3.x和新版本MyBatis-Plus之间有时会有兼容性隐患,尤其是mybatis-plus-spring-boot3-starter这个专门的适配包,和旧版的mybatis-plus-boot-starter用错的话,直接起步就报错。老项目里的Spring Boot 2.x写法,强行为迁移到Spring Boot 3.x,各种Bean加载异常会接踵而至。

前端的版本问题也不少。npm安装依赖时,如果报ELIFECYCLE错误,最常见原因是Node版本和依赖库不匹配。Element Plus要求Vue版本至少是3.2以上;Vite 5本身又要求Node 18以上。所以,一旦前端环境问题开始出现,先查Node版本,这会最靠谱的排查入口。

版本问题总结成一句话:启动一个新项目时,先确认官方文档的版本组合要求,不要一股脑把依赖加到pom.xml里就完事。依赖冲突和版本兼容,是比起业务代码本身更让人头疼的东西。

7. 部署上线,把你手搓的系统真正跑起来

7.1 后端打包运行

开发完成之后,后端项目用Maven打包非常方便。IDEA右侧Maven面板执行clean package命令,等待构建结束后,你会看到target目录下生成了一个jar包。这个jar包就是可以直接运行的文件。

在服务器上运行,纯命令行环境的话用nohup java -jar xx.jar > app.log 2>&1 &命令,让服务在后台运行。同时记得在application.yml里配置好生产环境的数据库地址和账号密码,端口号可以用server.port指定。启动后,先查看app.log日志,看到“Started Application in X seconds”基本就是启动成功了。

这里提醒一个细节:生产环境不要用root身份直接跑Java进程,建议建一个普通用户运行,权限最小化一直是部署的铁律。

7.2 前端打包与Nginx部署

前端项目执行npm run build,打包完成后会在dist目录下生成静态文件。把这些文件上传到服务器的某个目录,比如/opt/web,然后用Nginx服务它们。

Nginx配置核心非常简单:server块监听80端口,root指向静态文件目录,try_files配合Vue的history路由模式防止刷新页面出现404。如果后端接口地址和前端域名不同,需要在Nginx配置location /api块做反向代理,把请求转发到后端的8080端口。这样前端页面和后端接口在用户看来就是同一个端口提供的服务,既解决了跨域,又隐藏了后端端口。

部署完成后,打开浏览器输入服务器IP,看到登录页面正常渲染,输入账号密码登录成功,系统能正常增删改查,意味着你手搓这套管理系统,正式上线了。

最后说点实在的。我手写过好几套类似的管理系统,最大的感受是:这个东西看着简单,但一路走下来的技术点一点都不少,从权限设计到联调排错,每一步都是经验。如果你正在上手这套组合,建议别急着往代码里堆功能,先把数据库设计想透,把权限模型定下来,再动手写业务代码,后面会顺畅非常多。还有,遇到问题多看看日志文件,报错信息里面往往会直接告诉你答案。这个组合在未来很长一段时间里,依然会是管理系统的经典答案,掌握它,你的路子会宽很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询