资讯动态

SpringBoot2+Vue3+MyBatis-Plus兼职网站毕业设计全流程解析

发布时间:2026/10/25 4:37:59 来源:尧图企业网站定制
做兼职网站这类毕设项目我前前后后带过不少同学自己也在几个实际项目里完整走了一遍这套业务流程。看到这个标题里的技术栈组合第一反应是这应该是目前最主流的毕业设计选型了SpringBoot2负责后端接口Vue3做前端页面MyBatis-Plus省掉一堆手写SQLMySQL8.0存数据搭配一份写好的设计文档整个链路非常清晰。这篇内容我就围绕这个兼职网站的完整实现来拆从技术选型为什么这么定、数据库表怎么设计、前后端核心功能怎么落地到联调部署阶段最容易踩的坑一次性讲透。不管你是拿它做毕业设计、课程设计还是纯粹想练手前后端分离项目这套东西的参考价值都相当高。1. 项目整体设计与技术选型思路1.1 为什么是SpringBoot2 Vue3 MyBatis-Plus先说后端。SpringBoot2在这类单体项目中几乎是标准答案它的自动配置机制极大减少了繁琐的XML配置内嵌Tomcat让项目可以一键启动。对于兼职网这种业务复杂度中等、需要快速交付的系统SpringBoot的约定优于配置理念特别合适。你不需要像传统的SSM框架那样搞一堆配置文件一个启动类就能把整个Web服务跑起来。我见过不少同学纠结SpringBoot选2还是3。这里明确说一下SpringBoot2.x在当前阶段依然是最稳的选择尤其配合毕业设计常见需求。SpringBoot3要求JDK17很多机器上默认的JDK8环境跑不起来改环境成本高而SpringBoot2.x用JDK8就能完美运行兼容性最好。另外大量教程、依赖版本、报错解决方案都基于SpringBoot2出了问题更容易找到答案。MyBatis-Plus在标题里出现是有道理的。它本质上是个增强版的MyBatis单表CRUD几乎不用写SQL自带分页插件、条件构造器、代码生成器开发效率提升非常明显。兼职网的核心业务无非是用户、兼职信息、报名的增删改查这类标准操作用MyBatis-Plus的BaseMapper接口就能搞定开发者只需要关注那些真正需要手写SQL的复杂查询场景。而且它的逻辑删除、自动填充功能对这类信息管理系统来说实在太友好了后面细说。前端Vue3是目前的主流。相比Vue2Vue3的Composition API让代码组织更灵活配合Vite构建工具开发调试速度比Webpack时代快了一个量级。前端部分核心页面包括首页、兼职列表、兼职详情、发布兼职、个人中心、后台管理这些用Vue3 Vue Router Pinia或Vuex组合可以很清爽地实现。MySQL8.0的选择不用多解释现在本机装数据库基本默认就是8.x版本它支持窗口函数、公用表表达式等高级特性字符集默认utf8mb4对中文支持比5.7时代好很多。这套组合下来前后端分离架构清晰每个环节都踩在主流技术栈上无论是答辩还是面试都能拿出说得通的选型理由。1.2 角色权限与功能模块梳理兼职网站和普通的信息展示网站不同它的核心是连接——把有兼职需求的雇主和想找兼职的学生连起来。因此系统天然需要三种角色学生端注册登录、浏览兼职信息、搜索筛选、报名兼职、查看报名状态、收藏职位、管理个人简历。企业/雇主端注册登录、发布兼职、管理自己发布的职位、查看报名人员、处理报名申请、给兼职结算。管理后台用户管理、兼职信息审核、分类管理、公告管理、数据统计。这里有个关键设计点发布兼职信息不能直接上架必须经过管理员审核。这个流程虽然是很多同学容易忽略的细节但却是这类平台真实业务中必不可少的一环。它带来的好处是防止垃圾信息泛滥保证平台内容的可信度。在数据库设计里兼职信息表需要加一个status字段比如0待审核、1已通过、2已驳回、3已下架管理员通过后学生端才能看到这个状态机是整个兼职业务的核心。前端路由也要对应上这套角色逻辑。学生登录后跳转求职者视角的页面企业登录后跳转招聘者视角的页面管理员登录后进入独立的后台布局。这里推荐用路由守卫做权限控制前端判断token和角色信息不满足条件的重定向到登录页。当然真正的安全性还是后端接口层面控制前端路由守卫只是体验层面的优化。1.3 项目目录结构与后端分层设计好的项目结构能让你在写代码的时候少很多麻烦。我常用的后端包结构是这样规划的com.snail.job ├── config // 配置类跨域、拦截器、MyBatis-Plus配置 ├── controller // 控制层接收请求、返回结果 ├── service // 业务层核心逻辑处理 │ └── impl ├── mapper // 数据访问层继承BaseMapper ├── entity // 实体类对应数据库表结构 ├── dto // 数据传输对象前端传参封装 ├── vo // 视图对象返回给前端的响应数据 ├── common // 公共类统一返回结果、异常处理、常量定义 └── utils // 工具类JWT、文件上传等Controller层只做参数接收和结果返回不写业务逻辑Service层处理具体业务比如发布兼职要检查用户身份、内容完整性、自动填充创建时间Mapper层就是最基本的数据库操作。这种分层看起来简单但真正做到位并不容易。我见过很多同学的Service层几百行代码堆在一起各种判断逻辑嵌套调试起来非常痛苦。统一返回结果这个点也值得强调。前后端分离项目中前端需要一种通用的数据结构来判断请求是否成功。我一般定义成这样的格式{ code: 200, message: 操作成功, data: {} }所有接口都走这一个包装类前端拿到code为200再做后续处理否则弹出message里的错误信息。这么做的好处是前端Axios拦截器可以统一处理错误提示不用每个接口单独写一遍失败逻辑。2. 数据库设计与核心表结构2.1 用户表与扩展信息设计数据库是整个系统的地基表设计不合理后面写代码全是坑。兼职系统的核心表我拆成这几张用户表、兼职信息表、报名记录表、收藏表、公告表、兼职分类表。用户表是所有业务的基础设计的时候要注意把通用登录信息和角色扩展信息分开。基础字段包括id、用户名、密码加密存储、手机号、邮箱、头像、角色类型1学生、2企业、3管理员、状态、注册时间。然后针对学生和企业分别建扩展表学生扩展表存姓名、学校、专业、年级、个人简介、期望薪资等企业扩展表存公司名称、统一社会信用代码、公司规模、行业类型、公司简介、营业执照图片。为什么这么拆分因为学生和企业的属性差异很大全塞在用户表里会造成大量冗余字段。比如一个学生用户的企业信用代码字段永远是空的一个企业用户的学生年级字段也永远没意义。拆成扩展表后登录查询只查用户表展示详情时再连扩展表逻辑清晰表结构也干净。密码存储强烈建议用BCrypt加密这是Spring Security自带的支持方式。很多同学图省事用MD5但MD5在彩虹表攻击面前几乎形同虚设毕设答辩时如果被问到安全性的问题BCrypt是个拿得出手的答案。2.2 兼职信息表与状态流转设计兼职信息表是最核心的业务表字段设计直接影响前端页面展示的完整度。我的建议字段包括id主键发布人id关联用户表企业账号标题兼职名称分类id关联分类表比如家教、跑腿、促销、客服、技术开发等薪资类型1按小时、2按天、3按月、4项目制薪资范围最低值和最高值分开存工作地点省市区详细地址工作内容描述招聘人数已报名人数学历要求工作经验要求工作周期开始日期和结束日期联系人、联系电话状态0待审核、1招聘中、2已截止、3已下架、4已驳回浏览量、收藏量发布时间、更新时间注意薪资不要只存一个字符串比如100-200/天这样后续做筛选和统计很麻烦。拆分成salary_min和salary_max前端展示时拼接成100-200/天后端筛选时直接做范围比较这才是规范的做法。状态流转是兼职业务的核心逻辑。企业在发布页面提交后状态是0待审核管理员审核通过后变成1招聘中招聘人数满了或时间到期自动或手动变成2已截止管理员发现违规内容可以下架或驳回。这里涉及到一个常见问题报名人数不能超过招聘人数所以每产生一条报名记录兼职表的已报名人数就要更新同时要加一个事务防止并发情况下数据不一致。2.3 报名记录表、收藏表与公告表的关联设计报名记录表记录谁报名了哪个兼职字段包括id、兼职id、学生id、报名时间、状态、备注。状态设计上我建议用0待处理、1已通过、2已拒绝、3已完成。企业登录后看到报名列表可以点通过或拒绝学生端同步看到状态变化。兼职结束且学生正常完成工作后企业可以将状态改为已完成。这个流程虽然简单但每一步都需要在对应的Service方法里处理好关联更新。收藏表是最简单的关联表id、用户id、兼职id、收藏时间。查询时就是当前用户ID 兼职ID是否存在这条记录取消收藏就是删除记录。注意加上唯一索引防止用户重复收藏同一条兼职。公告表字段比较少id、标题、内容、发布时间、状态。管理后台发布公告前台首页或公告列表展示。有的同学还会加一个置顶字段用sort值控制展示顺序数值越大越靠前实现起来也不复杂。如果你想要更完善一点还可以加一张兼职申请审核日志表记录管理员对每个兼职的审核操作时间和审核意见。这样答辩的时候能讲出系统具备完整的操作审计功能属于加分项。2.4 MyBatis-Plus代码生成与逻辑删除配置表结构设计好之后最快的方式是直接用MyBatis-Plus的代码生成器一键生成实体类、Mapper接口、Service接口和实现类。生成完后手动调整一下特殊字段的注解就行比如表名映射用TableName、主键策略用TableId(type IdType.AUTO)、逻辑删除字段加TableLogic。逻辑删除是个特别推荐的功能。企业删除兼职信息时你肯定不希望物理删除数据库记录因为这意味着关联的报名记录、统计信息全部丢失。用逻辑删除实际执行的是UPDATE操作把deleted字段从0改成1查询时MyBatis-Plus自动拼接deleted0条件既保留了数据痕迹也不影响查询结果。全局配置只需要在application.yml里加一行mybatis-plus: global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0这样所有实体类的deleted字段都能自动生效不用每个Mapper手动写条件。3. 后端核心功能实现与关键细节3.1 基于JWT的登录认证与权限拦截前后端分离项目最常用的认证方案就是JWT无状态、不依赖Session、适合分布式部署。用户登录成功后后端生成一个包含userId和角色信息的token返回给前端前端每次请求在请求头里带上Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...后端的拦截器解析token取出userId放进ThreadLocal或请求上下文后续业务逻辑直接获取当前登录用户。注意JWT的密钥要配置在application.yml里不要写死在代码中。public class JwtUtils { // 生成token有效期建议设置2小时 public static String generateToken(Long userId, Integer role) { return Jwts.builder() .claim(userId, userId) .claim(role, role) .setExpiration(new Date(System.currentTimeMillis() 7200000)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } }权限拦截部分我建议做一个拦截器实现HandlerInterceptor在preHandle里做白名单排除。比如登录、注册、首页兼职列表这些接口不需要token其余接口必须校验。白名单列表集中在配置类里管理方便调整。public class AuthInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 放行OPTIONS预检请求 if (OPTIONS.equalsIgnoreCase(request.getMethod())) return true; String authHeader request.getHeader(Authorization); // 解析token失败则返回401前端判断后跳转登录页 } }这里特别提醒一个细节跨域请求时浏览器会先发一个OPTIONS预请求这个请求不带业务数据如果拦截器直接拦截前端拿不到响应就报跨域错误。所以代码里必须放行OPTIONS请求这是我见过新人踩得最多的坑之一。3.2 兼职信息发布、审核与列表检索企业发布兼职的接口逻辑不算复杂但要做的事不少。Controller接收发布人id和表单数据Service里先判断当前用户是否是已认证的企业账号然后补全初始化数据状态设为0待审核、浏览量设0、收藏量设0、发布时间设为当前时间。把所有字段从DTO拷贝到实体类后调用MyBatis-Plus的insert方法入库。管理员审核接口是另一个关键点。管理员查看待审核兼职列表点击通过后把状态从0改成1。这里要注意驳回操作最好要求管理员填写驳回原因并把这个原因展示给企业用户看方便修改后重新提交。我在实际项目里见过没做这个功能的结果企业用户不知道为什么被驳回只能凭感觉改容易产生重复驳回的死循环。兼职列表检索是系统最常用的功能也是最能体现查询功底的地方。学生端首页展示所有已审核通过的兼职支持按分类筛选、按关键字搜索、按薪资区间过滤、按发布时间排序。用MyBatis-Plus的LambdaQueryWrapper可以非常优雅地构建条件LambdaQueryWrapperJobInfo wrapper new LambdaQueryWrapper(); wrapper.eq(JobInfo::getStatus, 1) // 只查询已审核通过 .like(StringUtils.hasText(keyword), JobInfo::getTitle, keyword) .eq(categoryId ! null, JobInfo::getCategoryId, categoryId) .ge(minSalary ! null, JobInfo::getSalaryMax, minSalary) .le(maxSalary ! null, JobInfo::getSalaryMin, maxSalary) .orderByDesc(JobInfo::getPublishTime); PageJobInfo page jobInfoMapper.selectPage(new Page(current, size), wrapper);这段代码的核心优雅之处在于条件里带一个布尔判断参数条件为true时才拼接SQL片段。前端不传关键词时like条件自动跳过不需要写一堆if判断来拼接SQL。分页插件返回的Page对象里自带total总记录数、current当前页、pages总页数直接封装给前端。关于浏览量每次详情页被访问时执行一次incr操作UPDATE job_info SET view_count view_count 1 WHERE id ?。这个用UpdateWrapper的setSql方法实现比先查出来再赋新值再更新要高效得多也避免了并发覆盖问题。3.3 学生报名与收藏的业务逻辑报名接口是兼职系统里最容易出问题的地方因为涉及多个表的联动更新。我需要做的事情包括校验兼职存在且状态为招聘中。校验当前学生没有重复报名过这个兼职。校验当前报名人数未满。插入一条报名记录。更新兼职信息表的已报名人数加1。如果报名人数达到招聘人数自动将兼职状态改为已截止。这六步操作必须放在同一个事务里任何一个环节失败都要回滚全部操作。Spring的Transactional注解就能实现用法很简单但很多同学忘记在Service方法上加导致数据不一致。为了保险起见我还会在高并发的场景下用数据库乐观锁在兼职表加一个version字段更新时带上version条件防止多人同时报名导致超卖。毕设项目可能用不上这么复杂但能在文档里提一句答辩的时候就有东西讲。收藏就比较简单了先查询是否已存在记录不存在就插入存在就抛异常或返回友好提示。取消收藏直接根据userId和jobId删除记录。收藏列表页面需要关联查询兼职的标题、薪资、图片等基础信息这里可以用一个自定义SQL实现两表关联查询返回给前端的VO里包含兼职信息和收藏时间。3.4 文件上传与图片存储方案兼职信息和企业资质往往需要上传图片比如企业营业执照、兼职宣传图。SpringBoot处理文件上传比较简单核心代码就几行PostMapping(/upload) public ResultString upload(MultipartFile file) { String originalFilename file.getOriginalFilename(); String extName originalFilename.substring(originalFilename.lastIndexOf(.)); String fileName UUID.randomUUID() extName; // 存储到本地目录建议按日期分目录 String datePath LocalDate.now().toString(); File dir new File(UPLOAD_DIR datePath); file.transferTo(new File(dir, fileName)); return Result.success(/upload/ datePath / fileName); }文件名一定要用UUID重命名不能直接用用户上传的文件名。原因是可能有中文、特殊字符甚至路径穿越风险直接存储会引发一系列问题。图片访问的话需要配置一个资源映射类把本地磁盘路径映射到URL路径否则前端无法通过浏览器直接访问。静态资源映射的代码如下Configuration public class WebMvcConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadDir); } }这个配置很容易被忽略很多同学上传成功后图片404就是缺了这一步。4. 前端Vue3项目搭建与页面实现4.1 Vite初始化与管理后台布局前端部分用Vite创建Vue3项目命令很简单npm create vitelatest snail-job-front -- --template vue创建完进入项目目录安装依赖然后装上路由、状态管理和UI组件库。UI组件库我用的是Element Plus它和Vue3的契合度最高表格、表单、弹窗、分页组件都能满足后台管理系统的需求。项目的目录结构建议把前台用户端和后台管理端分开不要混在一起写。我常用的目录规划src ├── api // 接口请求方法封装 ├── assets // 静态资源 ├── components // 公共组件 ├── layout // 页面布局组件 ├── router // 路由配置 ├── store // 状态管理Pinia ├── utils // 工具方法 └── views // 页面组件 ├── home // 前台页面 └── admin // 后台管理页面前台页面想做得好看一点不要光依赖UI库的现成组件适当写一些自定义样式和布局。比如首页的兼职卡片列表、搜索栏的筛选组件、职位的标签效果这些用Tailwind CSS或者直接用Sass写都行。不过我建议新手别在样式上花太多时间保证干净整洁、功能完整就好毕业设计更看重的是功能链路完整性和逻辑严谨度。4.2 路由守卫与Axios请求拦截封装路由守卫是前端权限控制的第一道关卡。Vue Router的beforeEach钩子里检查目标路由是否要求登录如果要求登录且当前没有token就跳转登录页。如果已经登录但token过期接口请求时会返回401这时候在Axios响应拦截器里统一清除token并跳转登录页。Axios封装是每个前端项目的必备环节。请求拦截器负责在每次请求前从localStorage取出token拼到请求头里。响应拦截器负责统一处理返回的code值和HTTP状态码service.interceptors.response.use( (response) { const res response.data if (res.code 200) return res // 业务错误统一提示 ElMessage.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) }, (error) { if (error.response?.status 401) { // token失效跳转登录页 router.push(/login) } return Promise.reject(error) } )这样写完之后每个页面调用接口只需要关心返回的data数据不需要重复处理错误提示。我见过很多项目每个请求单独写try catch、单独弹错误提示代码非常冗余。统一的拦截器封装完开发效率提高的幅度非常明显。4.3 首页兼职列表与搜索筛选实现首页是学生对整个系统的第一印象也是展示项目完成度的门面。我建议首页做一个大搜索框下面按分类展示兼职卡片卡片上显示标题、薪资、公司、地点、发布时间等关键信息。列表数据从后端分页接口获取前端维护页码和每页条数点击分页组件时重新请求数据。筛选条件我习惯用一个响应式对象存储const queryParams reactive({ current: 1, size: 10, keyword: , categoryId: null, minSalary: null, maxSalary: null, sortField: publishTime, sortOrder: desc })点击搜索时重置页码为1点击分页时更新页码两个操作触发同一个获取列表的函数即可。Element Plus的分页组件Pagination自带layout切换设置好current-page和page-size的v-model绑定就行。4.4 企业发布兼职表单与管理页面企业端做两个核心页面就够了发布兼职表单页和兼职管理列表页。发布表单的字段对应后端DTO的字段用Element Plus的Form表单加校验规则。这里注意校验规则要前后端双重设置比如标题不能为空、薪资必须是数字、联系电话格式校验等。前端校验提升用户体验后端校验是安全底线缺一不可。发布成功后清空表单并跳转到管理列表页。兼职管理列表页展示当前企业发布的所有兼职每行操作有编辑、下架、查看报名者。点击查看报名者会弹出一个抽屉或对话框里面展示这个兼职的报名列表每条报名记录有学生基本信息、报名时间以及通过/拒绝操作按钮。这个功能是企业-学生形成闭环的关键页面做的时候注意操作完成后要刷新当前列表数据。下架操作建议做一个二次确认弹窗避免误操作这个细节对用户体验提升很明显。5. 部署联调实战与文档撰写要点5.1 本地开发环境配置与启动步骤本地环境需要准备的东西有JDK 8及以上、Maven 3.6、Node.js 14、MySQL 8.0、Navicat或任意数据库管理工具。项目拿到手之后我建议按下面的顺序启动第一步用Navicat新建数据库注意字符集选utf8mb4排序规则选utf8mb4_general_ci。然后导入项目里提供的SQL文件里面应该包含建表语句和初始化数据。第二步用IDEA打开后端项目等待Maven下载依赖。这一步可能比较慢如果网络不好可以在Maven的settings.xml配阿里云镜像。然后修改application.yml里的数据库用户名和密码改成自己本机的配置。第三步启动SpringBoot项目的Application类。如果控制台出现Tomcat started on port 8080说明后端启动成功。第四步进入前端项目目录执行npm install装依赖。安装过程同样建议配置npm国内镜像源npm config set registry https://registry.npmmirror.com。然后npm run dev启动开发服务器默认端口5173。第五步浏览器访问前端地址尝试注册一个账号并登录。接口请求正常、数据正常回显说明前后端已经联通。5.2 常见端口冲突与跨域联调问题前后端联调阶段最容易遇到的是跨域问题。开发环境下前端运行在5173端口后端在8080端口两者端口不同浏览器拦截了跨域请求。解决方式有两种第一种是后端配置全局CORS在SpringBoot项目中添加一个配置类允许指定来源访问。第二种是前端在Vite配置文件里设置代理把请求转发到后端地址// vite.config.js export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ) } } } })我推荐第二种方案因为生产部署时Nginx本身就会做代理开发和生产的行为更一致。但要注意后端接口的路径如果本身就是/api开头代理配置里的rewrite就可以省略。这个细节可以在项目的文档里写清楚不然别人看代码容易绕晕。5.3 项目文档撰写与答辩准备思路标题里特别标注了【含文档】说明配套文档是这个项目的重要组成部分。文档的核心作用不是简单记录有哪些功能而是把设计思路、数据库建模逻辑、技术难点和测试过程完整呈现出来。我写这类项目的文档一般按照这样的目录组织绪论项目背景、研究意义、国内外现状。需求分析功能性需求、非功能性需求、可行性分析。系统设计总体架构、功能模块设计、数据库设计ER图、表结构。系统实现核心功能页面展示、关键代码片段、实现逻辑说明。系统测试测试用例表、测试结果、测试结论。总结与展望。答辩准备上一定要把技术选型的理由、表结构设计的合理性、核心模块业务流程、遇到的问题和解决方案这四块内容备足。评委会围绕你怎么实现、为什么这么做来提问。比如用MyBatis-Plus而不是原生MyBatis的理由、为什么用JWT不用Session、数据表之间怎么关联的这些都要能做到流畅回答。最好自己画一张系统架构图和数据表ER图贴到文档里也方便答辩时展示。6. 常见问题排查速查表与避坑实录6.1 后端启动失败与数据库连接报错后端启动报错很常见但90%的问题集中在数据库连接上。典型的报错信息是Cannot create PoolableConnectionFactory Access denied for user rootlocalhost第一个原因是MySQL没启动或者数据库连不上检查数据库服务和端口。第二个原因是密码不对或者当前用户不允许从localhost连接。改application.yml里的spring.datasource.username和password即可。还有一种容易忽略的情况是MySQL 8.0的认证方式问题如果项目用的驱动版本太老会报Public Key Retrieval is not allowed需要把连接URL加上allowPublicKeyRetrievaltrue参数。另一个高频报错是端口被占用启动时提示Port 8080 was already in use。Windows下用netstat -ano | findstr 8080查占用进程然后用任务管理器结束掉对应的PID。也可以在application.yml里把server.port改成8081不过改了之后前端代理也要对应修改。6.2 Maven依赖下载失败与包缺失Maven下载依赖失败也是新手机器上经常发生的事情。主要表现是pom.xml里报红运行时报类找不到。思考一下是什么原因本地的settings.xml没有配置国内镜像下载速度太慢导致超时或者仓库里存在损坏的下载文件。解决方案是清空本地仓库的lastUpdated文件后重新加载Maven项目# 在Maven本地仓库目录执行 find ~/.m2/repository -name *.lastUpdated -delete然后IDEA里刷新Maven项目让依赖重新下载。如果还是失败检查一下pom.xml里SpringBoot父依赖版本号是否真实存在这一个版本号写错能卡住整个项目我见过不止一个同学在这个问题上耗了很久。建议直接对照官方仓库确认版本号不要随手填一个。6.3 前端接口406/415错误与参数格式不匹配前端请求后端接口时报406或415的错误通常不是后端逻辑问题而是请求头或参数格式不匹配。用Axios请求时如果不指定Content-Type默认是application/json后端用RequestBody接收两边对应就没问题。但如果后端用RequestParam接收前端必须用application/x-www-form-urlencoded的格式传参。一致性问题在对接前后端接口时非常关键建议写接口文档的时候把每个接口的接收方式标注清楚减少联调阶段的返工。415通常是我见的另一种情况前端传的JSON字符串和后端DTO的字段对不上多传了后端不认识的字段或者传的类型不对。这种情况要看后端日志里最具体的报错信息比如HttpMessageNotReadableException多半就是类型转换失败。前端的数字字段传成字符串后端Integer接不住就会报这个异常。解决方案是前端传参时严格对照DTO的字段和类型也可以在DTO里加JsonFormat注解做格式约束。6.4 前后端数据不一致与缓存更新的坑这个问题比较隐蔽。我在一个项目里遇到过这样的场景管理员修改了兼职信息的状态学生端刷新页面后依然看到旧状态。排查到最后发现是几张表的查询结果被MyBatis的一级缓存和二级缓存“惯坏了”。默认情况下MyBatis的二级缓存是关闭的一级缓存的生效范围只在同一个SqlSession内。如果每次请求都新开SqlSession一般不会出现问题。但如果你引入了Redis或本地缓存那就要考虑缓存失效策略。我的建议是这类管理系统在数据实时性要求高的情况下尽量少引入额外的缓存层。数据库查询加了索引之后单表几千条数据的查询性能完全够用。就算以后数据量大了再考虑加缓存也不迟。用缓存要付出的缓存更新、删除策略代价远大于暂时的性能提升这个取舍经验在真实开发中特别重要。实操体会与进一步扩展方向整体做下来这套SpringBoot2 Vue3 MyBatis-Plus MySQL8.0的兼职网项目最大的特点就是技术主流、难度适中、闭环完整。从学生的注册登录、浏览报名到企业发布管理、筛选处理再到管理员审核维护整个业务链条从头到尾都能跑通作为毕业设计或者练手项目都非常合适。我个人在实际操作中体会最深的一点是项目写代码的过程里一定要自己把数据库表从头设计一遍不要拿到SQL文件直接导入就开干。你只有在设计表的时候想清楚每个字段的用途、每张表之间的关联后面写代码才会心里有底。我见过不少同学表结构是网上找的代码也是照着模板敲的遇到问题根本不知道从哪下手排查。哪怕你最终用的表结构和别人一样自己也动手画一遍ER图、写一遍建表语句整个理解深度差别非常大。最后再分享一个可以继续扩展的方向。这套系统做好了之后可以再加一个站内私信功能用WebSocket实现学生和企业之间的即时沟通。这样前后端就涉及到了WebSocket协议的处理项目的技术含金量能再上一个台阶。另外把支付功能接进来也不是做不到兼职完成后的薪资结算如果能在平台上走一笔模拟支付流程从用户体验角度就完整了。不过这些都是后话先把当前的业务链路做扎实、把每一步的原理搞清楚后面扩什么功能都不难。如果你打算拿这个项目做毕设我的建议是不要在边界功能上堆量把核心链路的代码质量做好文档写扎实比做一堆花哨但讲不清的功能要强得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑