☰
SpringBoot+Vue3+MyBatis前后端分离系统源码实战解析
2026/10/3 18:01:07 网站建设 项目流程

我先跟你交个底。所谓的“Java SpringBoot+Vue3+MyBatis 网站系统源码|前后端分离+MySQL数据库”,说白了就是一套现成的全栈Web项目骨架,后端用SpringBoot写接口,前端用Vue3做页面,中间通过MyBatis操作MySQL数据库。它解决的是“从零搭一套可用系统太耗时”的问题——尤其是毕设、课程设计或者公司内部小系统的快速交付场景,拿过来改改就能跑。这篇文章我按照实际开发者的视角,把拿到源码后怎么理解、怎么启动、怎么改、怎么避坑,全部拆开讲透。适合正在学SpringBoot和Vue3的Java开发者,也适合准备做毕设但不知从哪下手的同学。

1. 先说清楚:这套代码到底解决了什么问题

很多人在网上找源码时有个误区,以为源码就是“点开即用的成品”。实际上,如果是前后端分离的架构,它交付的是一整套工程:后端是一个Maven项目,前端是一个Node项目,数据库是一份SQL脚本。你拿到手的第一步不是打开浏览器看效果,而是让这些模块能互相通信。这套源码的价值在于,它在SpringBoot、Vue3、MyBatis、MySQL这四样技术之间,提前帮你铺好了路——路由写好了、接口规范定好了、公共组件封装好了、数据库关系建好了,你只需要在这个骨架上填自己的业务。

1.1 前后端分离到底是什么

简单说,后端项目只负责输出JSON数据,不关心页面长什么样;前端项目只负责渲染页面和发起HTTP请求,不关心数据存在哪张表。两者通过接口(API)对接。比如你要做一个“用户列表”功能,后端提供一个/api/user/list接口,前端写一个Vue页面调用这个接口,然后把返回的数据循环渲染成表格。

这种做法的好处是:开发时不需要启动一个巨大的单体应用,前端跑自己的Vite服务,后端跑SpringBoot,各改各的,互不干扰;部署时也能分开处理,前端静态文件丢到Nginx,后端打成Jar包丢到服务器。这套源码之所以采用这种结构,就是为了贴近真实企业项目的开发模式,而不是那种把所有HTML塞进templates目录的老式写法。

1.2 技术选型不是拍脑袋,每个组件都有它的理由

后端用 SpringBoot 而不是 SSM,是因为SpringBoot内置了Tomcat,简化了配置,你不再需要手动去配置一堆XML。用 MyBatis 而不是 JPA,是因为MyBatis的SQL是手写的,控制力强,复杂的多表联查写起来更直观,国内企业用的也多。前端用 Vue3 而不是 Vue2,是因为Vue3的组合式API(Composition API)在逻辑复用上更灵活,而且生态已经成熟。数据库选 MySQL,是因为开源免费、部署简单、资料多,学校里和中小型公司基本都是它。

这几个技术拼在一起,刚好覆盖了“数据存储、后端业务、接口封装、前端展示”这条完整链路。你把这套源码跑起来,等于亲眼看了一遍“数据从MySQL表里被MyBatis取出来,SpringBoot包装成JSON,Vue3拿到后渲染到浏览器”的全过程。

2. 从代码结构看整套系统的设计思路

拿到源码之后,别急着点启动按钮。先花十几分钟把目录结构过一遍,这会帮你在后续改代码时快速定位文件。前后端分离项目的目录结构是很有套路的,看懂了它,你之后看任何同类项目都能事半功倍。

2.1 后端分层:controller/service/mapper/entity

后端项目一般都长这样:

  • entity(或pojo):数据库表的映射实体类,一张表对应一个类,字段名和表字段一一对应。
  • mapper:MyBatis的接口层,里面定义方法,比如selectUserById(Integer id),SQL可以在注解里写,也可以写在XML文件里。
  • service:业务逻辑层,处理具体业务。比如查询用户时,先判断参数是否合法,再调用mapper。
  • controller:接收前端请求,调用service,返回结果。它是整个后端对外的唯一入口。

这套分层的目的很明确:各层职责单一。controller不写SQL,service不直接返回JSON,mapper不处理业务。你改业务逻辑时只改service,不影响接口对外结构;你改SQL时只改mapper,不用动service。这个设计思路如果看懂了,你就知道为什么很多企业代码都喜欢这样组织——它牺牲了一点代码量,但换来了维护上的清晰。

2.2 前端Vue3项目结构和API封装

前端Vue3项目通常长这样:

  • src/api:存放所有接口调用文件,每个页面模块对应一个js/ts文件,统一封装axios请求。
  • src/router:路由配置文件,决定了URL对应哪个页面组件。
  • src/views:页面组件,一个文件代表一个页面。
  • src/components:公共组件,比如表格、弹窗、上传。

这套源码里最值得借鉴的是API的封装方式。你会在src/api里看到类似这样的代码:

import request from '@/utils/request' export function getUserList(params) { return request({ url: '/api/user/list', method: 'get', params }) }

统一通过axios.create()配置好基础URL,比如http://localhost:8080,然后所有请求都走这同一个入口。好处是:如果后端地址变了,你只需要改一个地方;如果要做统一的错误提示和Token校验,也只需要在拦截器里加一段逻辑即可。

2.3 数据库表和字段设计的几个考量

这套源码附带的SQL脚本里,表设计有几个通用套路值得你注意:

  • 主键统一用自增id:好用、好联查,不用像UUID那样担心索引碎片。
  • 每张表都带create_time和update_time:这就是审计字段,排查数据问题时非常有用。
  • 逻辑删除字段:很多表的删除都不是物理删除,而是通过一个deleted字段标记。

实际开发中,字段命名尽量和Java实体类的驼峰命名对应好。MyBatis支持开启驼峰映射(map-underscore-to-camel-case: true),这样数据库的user_name能自动映射到Java的userName,省去大量手动resultMap配置。如果你把表字段改成下划线风格,保持这个开关开启,能省很多事。

3. 核心配置与源码使用攻略(实操部分)

这部分才是真正的干货。我以“拿到源码后从启动到改造”的顺序来讲,每个步骤都是实际操作过的,你照着做就能跑起来。

3.1 拿到源码后的标准启动流程

第一步,先准备环境。后端需要JDK 8或JDK 11(看项目用的SpringBoot版本,如果SpringBoot是3.x就必须JDK 17以上,这点非常多人踩坑),前端需要Node.js 16以上,数据库需要MySQL 5.7或8.0。

第二步,导入SQL脚本。打开MySQL客户端(Navicat或命令行),新建一个数据库,比如shop_db,然后把源码里的.sql文件拖进去执行。这一步的目的不是看数据,而是让表结构落在你的机器上。

第三步,配置后端。用IDEA打开后端目录,在application.yml或application.properties里改三样东西:数据库地址、用户名、密码。常见配置如下:

spring: datasource: url: jdbc:mysql://localhost:3306/shop_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver

第四步,启动后端。直接运行主类上的main方法,观察控制台。看到 “Tomcat started on port(s): 8080” 就说明后端起来了。

第五步,启动前端。在Vue项目根目录打开终端,依次执行:

npm install npm run dev

看到 “Local: http://localhost:5173” 就说明前端起来了。这时打开浏览器访问这个地址,如果一切正常,你就会看到系统登录页。

第六步,联调。前后端端口通常不同,比如后端8080、前端5173,所以前端需要配置代理或者设置跨域。代理配置在vite.config.js:

export default defineConfig({ server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } })

配置好之后,前端发/api开头的请求,Vite会自动转发给后端,这样就不会有跨域问题了。

3.2 MyBatis配置与SQL映射的关键点

MyBatis在SpringBoot里一般不用写配置文件,靠注解和XML都可以工作。但有几个配置项我建议你改数据库后顺便确认一下:

第一,XML文件的存放位置。如果你在resources/mapper目录下看到一堆XML文件,那在application.yml里必须有这样一段配置:

mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.entity

没有这段配置,MyBatis就找不到SQL语句,启动时不会报错,但一调用接口就会报 “Invalid bound statement”。

第二,打印SQL日志。开发阶段一定要打开SQL日志,不然你排查问题时根本不知道MyBatis执行了什么:

mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

打开后,每次执行SQL都会在控制台打印出来,包括参数值。这是整个开发过程中最有用的调试手段之一。

第三,手写SQL时的注意点。XML里写<这种尖括号要转义,用&lt;代替;拼接条件时优先用<where>标签,它能自动去掉多余的AND;<foreach>用于批量操作时,collection属性要写对,传List就写list,传数组就写array。

3.3 SpringBoot配置文件中那些容易被忽略的坑

配置文件是小项目的大坑,我列几个最常见的:

端口冲突:本机8080端口被占用时,后端起不来。改端口行,直接改server.port,比如8081。但注意,如果你改了端口,前端代理的target也要跟着改。

MySQL版本与连接驱动问题:MySQL 5.7和8.0的驱动类不一样。MySQL 8的驱动类是com.mysql.cj.jdbc.Driver,还要加上useSSL=false和serverTimezone=Asia/Shanghai。很多人遇到的 “SSL连接错误” 或 “The server time zone value” 报错,就是因为这两项少了一项。URL里必须带serverTimezone这个参数。

SpringBoot版本太高导致的问题:如果你的JDK版本是1.8,但SpringBoot是3.x,启动会直接报错。查看一下pom.xml里的parent版本,如果<version>是3开头,你必须用JDK 17。这也是为什么我建议先看版本再准备环境。

3.4 前端Vue3的快速改造方法

拿到前端项目后,改页面其实是有套路的。

先看路由文件/src/router/index.js,里面定义了登录页、首页、用户管理等路由。如果你想加一个“商品管理”页面,先在里面加一条路由记录,指向新的Vue组件文件。然后去/src/views/goods/index.vue里新建页面,按已有页面的结构复制一份再改。

前端和后端联调时,注意接口路径。通常后端接口都带/api前缀,前端封装的request工具类里也配了基础路径baseURL: '/api'。如果你发现接口报了404,先确认是不是前缀对不上。

改样式时优先用已有的CSS变量或布局组件,这套源码里一般会封装好布局框架(Layout组件),页面内容嵌进去就行,不建议去改动布局本身的代码。

4. 联调中踩过的坑与排查技巧

跑通源码不算本事,能在遇到问题时快速定位才叫真功夫。我把从这套项目里实际遇到过的、以及同类项目里频繁出现的问题整理一下,每条都给了排查思路。

4.1 CORS跨域问题

现象:前端控制台报 “Access-Control-Allow-Origin” 错误,请求发出去了,但浏览器拦截了响应。

原因:前端和后端不在同一个域名或端口,浏览器出于安全策略拦截了跨域请求。

排查思路:先确认前端代理是否配好。如果配了代理还报错,再检查后端是否有全局跨域配置。一个典型的后端跨域配置长这样:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE") .allowCredentials(true) .maxAge(3600); } }

注意一个坑:如果你配置了拦截器并且拦截了/**,跨域配置可能被拦截器挡掉,导致请求被阻断。这种情况要在拦截器里放行OPTIONS请求,或者直接在拦截器代码中对OPTIONS请求直接返回。

4.2 时间格式化不一致

现象:后端返回的时间是 “2024-01-01T12:00:00” 这种格式,前端想要的却是 “2024-01-01 12:00:00”。

原因:SpringBoot默认的JSON序列化对LocalDateTime用的是ISO标准格式,和前端的显示要求不一致。

解决办法:在application.yml里统一设置格式化:

spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8

或者在后端实体类的LocalDateTime字段上加注解@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")。

4.3 数据库连接失败

现象:后端启动时报Could not create connection to database server或者Access denied for user。

原因:大部分是用户名密码错误、MySQL服务没启动、或者连接URL里的参数不对。

排查思路:

  • 确认MySQL服务已启动(Windows下到服务管理器看MySQL80是否在运行)。
  • 确认密码无误。“root/root” 和 “root/123456” 这种常见组合换着试一下。
  • 确认数据库确实是本地。如果连接远程数据库,URL里要写IP,而且远程MySQL要开放3306端口。

4.4 MyBatis字段映射对不上

现象:前端显示的表格里,某些字段是 undefined。

原因:数据库字段是下划线命名(比如user_name),Java属性是驼峰命名(比如userName),而MyBatis的map-underscore-to-camel-case没有开启,或者没有写resultMap。

排查思路:先在配置文件里加上驼峰映射开关:

mybatis: configuration: map-underscore-to-camel-case: true

如果还不行,就去查mapper的XML,看select语句的返回类型是否写了resultMap。写resultMap是最保险的办法,但工作量大;开了驼峰映射对于简单对应足够了。

4.5 常见问题速查表

问题现象可能原因快速解决办法
后端启动报端口被占用8080被其他程序占用改server.port,同时改前端代理target
前端npm install报错Node版本不兼容用nvm切换Node到16.x或18.x
页面能打开但接口404前后端接口前缀不一致核对后端Controller的RequestMapping和前端api请求路径
接口报500多半是SQL出了错打开MyBatis SQL日志,定位具体SQL语句
上传文件后访问不到图片静态资源路径没映射配置spring.web.resources.static-locations或自定义映射
前端页面请求一直pending请求没发出去或被代理拦截检查vite代理配置和浏览器控制台NetWork标签

5. 这套源码还能怎么扩展

源码给人的价值在于提供一个起点。当你能跑起来、能看懂结构之后,这套骨架可以做很多有意思的扩展。

你可以把登录模块改成基于JWT的单点登录,在原来的登录接口里生成Token,前端把Token存在请求头里,后端写一个拦截器做Token校验;你可以把文件上传模块接入MinIO,实现对象存储;你也可以把用户管理的权限接口细化,做成RBAC权限模型,给不同角色不同菜单。比如我之前拿这套结构改过一个校园教职员工考勤管理系统的壳子,只是换掉了业务表、加了几张业务表和对应页面,代码框架本身完全不用动。SpringBoot+Vue3这个组合的好处就是:框架是稳定统一的,业务之间差别再大,也只是换数据、换接口、换页面的问题。

6. 我在实际操作中的几点心得

最后再分享几个不算正规教程但非常实用的心得。

第一,先改配置后跑通,一步一步来。不要指望一次启动成功。先把数据库跑通,再启动后端,再启动前端,每一步出了问题都能定位到对应模块。乱改别人的代码再一起启动,出了问题根本不知道是谁的锅。

第二,多利用控制台。后端控制台的报错信息、前端浏览器的Network和Console面板,80%的问题都能从这里找到线索。很多人在后端报错时只盯着红色提示,却忽略了下方的堆栈里已经明确告诉你“哪个文件第几行出的错”。多看几行,往往就好解决了。

第三,数据库里不要乱加数据。搞之前先备份,搞坏了随时能恢复。即使是本地测试,一条错误的SQL也可能让你折腾半天。

第四,学会用Git做版本管理。哪怕只是本地的仓库,改坏了代码也能回滚,省去重来一遍的痛苦。

如果让我说这套源码最值钱的地方是什么,我会说是它把前后端分离项目最常见的配置、目录结构和联调流程都做成了可以直接对照参考的样子。你照着它走一遍,等于把SpringBoot、Vue3、MyBatis、MySQL四门技术串了一遍真实链路。这套经验,比代码本身更有价值。

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

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

立即咨询