拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Spring Boot+Vue垃圾分类毕设:分层、权限与排错实战

简介这份资源是面向高校计算机专业毕业设计场景的论文参考文档围绕基于Spring Boot的城市垃圾分类管理系统展开适合正在选题、撰写论文或需要了解同类系统设计思路的学生与开发者参考。压缩包内共1个docx文档约1.13MB内容以毕业论文正文为主体涵盖摘要、目录、绪论、相关技术介绍以及系统关键技术点分析等章节可帮助读者快速把握论文的整体结构与写作框架。文档详细梳理了系统的技术栈与开发环境包括Java语言、Spring Boot框架、B/S与MVC架构、MySQL 5.7数据库、MyBatis持久层以及Vue前端技术并逐一说明了用户管理、字典管理、论坛管理、公告管理、垃圾管理、垃圾收藏与留言管理、留言板、政策管理和管理员管理等十余个功能模块同时给出系统特点与关键技术点的分析论述便于对照理解项目功能划分与论文论述逻辑。目前已有203人浏览学习可作为毕业设计论文写作与选题论证的参考资料。1. 一份垃圾分类毕设论文背后到底该有哪些可运行的工程判断论文里写着 SSM摘要里却写了 Spring Boot源码包描述又是 SpringBoot MyBatis Vue 的前后端分离结构。这不是笔误而是大多数高校毕设的真实状态论文正文沿用了早年模板实际工程早被重构过一轮。如果只按论文目录去搭项目你会得到一堆能跑但说不清为什么这样分层的东西。真正值得先想清楚的是垃圾类别、投放点、积分记录这几张表怎么切权限怎么落到user/admin两张主体上以及论坛、留言这类社交属性模块该不该和核心业务表复用同一套评论结构。这套系统面向两类人一类是要在两周内把源码包改成自己能答辩的版本的学生另一类是想拿它当 Spring Boot 分层练习模板的后端初学者。它解决的不是城市垃圾分类这个宏大命题而是分类字典、投放记录、收藏留言、政策公告这几件事的增删改查与权限隔离。下面从表结构、分层、接口、权限到排错按能复现的顺序拆开讲。2. 垃圾分类业务表结构设计与 Spring Boot 分层落地2.1 从垃圾实体到收藏、留言的字段取舍论文里给了 E-R 图但只有实体没有关系基数。实际建表时核心是garbage、garbage_collection收藏、garbage_message留言、notice、policy、forum、dictionary这几张。垃圾实体建议至少包含分类外键、名称、图片、描述、投放指引。-- 垃圾信息表分类通过 dic_code 关联字典表避免硬编码分类枚举 CREATE TABLE garbage ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, garbage_name VARCHAR(100) NOT NULL COMMENT 垃圾名称, dic_code VARCHAR(32) NOT NULL COMMENT 分类字典编码关联 dictionary.dic_code, cover_img VARCHAR(255) DEFAULT NULL COMMENT 图片路径, guide_text TEXT COMMENT 投放指引, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), KEY idx_dic_code (dic_code), KEY idx_name (garbage_name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT垃圾信息表; -- 收藏表用联合唯一索引防止同一用户重复收藏同一条垃圾信息 CREATE TABLE garbage_collection ( id BIGINT NOT NULL AUTO_INCREMENT, garbage_id BIGINT NOT NULL COMMENT 垃圾ID, user_id BIGINT NOT NULL COMMENT 用户ID, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_user_garbage (user_id, garbage_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT垃圾收藏表;dic_code指向字典表而不是枚举列好处是运营侧改分类不用发版这和热搜里常提的springboot配置思路一致——可变的东西别写死在代码和表结构里。uk_user_garbage这个联合唯一索引是关键收藏功能如果不加它前端连点两次就会插两条重复记录后期统计多少人收藏过直接失真。idx_dic_code保证按分类筛选垃圾列表时不走全表扫描。留言表和收藏表结构相近但要多一个parent_id支持二级回复并加is_read标记给管理员做未读提示。论坛帖子和留言板是两套语义前者有标题和板块后者是纯文本流不建议合并成一张表——合并之后查询要不停用type字段过滤索引选择性会变差。2.2 Spring Boot 分层与 MyBatis 映射的落法项目用 Spring Boot 替代了论文正文里的 SSM本质是把 Spring、SpringMVC、MyBatis 的 XML 装配换成了起步依赖加注解。目录分层按controller / service / service.impl / mapper / entity / vo走Mapper 接口和 XML 放同一包路径下靠mybatis.mapper-locations扫描。# application.yml 关键片段 server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/garbage_sort?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.garbage.entity configuration: map-underscore-to-camel-case: truemap-underscore-to-camel-case: true让garbage_name自动映射到实体garbageName省掉大量resultMap。serverTimezoneAsia/Shanghai不加的话高版本 MySQL 驱动写时间会差 8 小时这是毕设里最常见的数据存进去时间不对的根因。Service 层写法上收藏这个动作要同时处理唯一约束和友好提示不能直接把 SQL 异常抛给前端Override public Result collect(Long garbageId, Long userId) { // 先查是否已收藏命中则直接返回避免依赖数据库唯一索引报错 Long count collectionMapper.countByUserAndGarbage(userId, garbageId); if (count ! null count 0) { return Result.fail(已收藏请勿重复操作); } GarbageCollection entity new GarbageCollection(); entity.setGarbageId(garbageId); entity.setUserId(userId); return collectionMapper.insert(entity) 0 ? Result.ok() : Result.fail(收藏失败); }这里先查询再插入看起来比直接insert多一次 IO但在并发不高的校园项目里更可控用户看到的是已收藏而不是一串DuplicateKeyException。Result用统一封装类code msg data三段式前端 Vue 的拦截器好统一处理。注意countByUserAndGarbage的返回值用Long而不是int因为 MyBatis 某些版本下count(*)映射到int在特定场景会有兼容性提示统一用包装类型更稳。2.3 字典表驱动的分类下拉与前端联动字典表设计成dic_code / dic_name / code_index三列是这套系统最值得抄的一点。管理员在后台维护可回收物、有害垃圾、厨余垃圾、其他垃圾四个分类每个分类下挂多个具体垃圾。前端做二级联动时第一级从字典表拿第二级按dic_code查garbage。字段类型说明是否可为空idint主键否dic_codevarchar(32)分类编码业务外键是dic_namevarchar(64)分类显示名是code_indexint排序序号是remarkvarchar(255)备注是code_index决定前端下拉顺序不加的话分类会按主键乱序显示。这个字段在毕设答辩里常被问为什么不用 id 排序答案就是 id 是自增物理序code_index才是业务序运营调顺序不用改数据。前端 Vue 侧用一次接口拿全量字典缓存在 store 里避免每次进页面都请求。3. 权限、登录与接口文档的工程化处理3.1 登录态与角色隔离的实现方式系统有user和admin两类主体论文只画了登录流程图没讲会话怎么保存。常见做法是 JWT 放Authorization头或者更简单的 session 拦截器。毕设规模下 session 够用但要注意跨域和前后端分离时的 cookie 携带。Configuration public class WebConfig implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns(/admin/**) // 后台接口统一切面 .excludePathPatterns(/admin/login, /admin/captcha); } }拦截器按路径前缀区分权限/admin/**必须管理员身份/api/**走普通用户校验公共的公告和政策查询放行。这样比在每个 Controller 方法里写if (role ! ADMIN)清爽也不会漏。AuthInterceptor里从 session 或 token 解析出角色不匹配直接返回 401前端拦截器看到 401 跳登录页。3.2 全表查询、分页与条件组合的接口写法后台管理列表几乎都是带条件分页查询这是毕设代码最容易写成性能雷区的地方。用 MyBatis 动态 SQL 组合条件配合 PageHelper 分页select idselectPage resultTypecom.example.garbage.entity.Garbage SELECT id, garbage_name, dic_code, create_time FROM garbage where if testdicCode ! null and dicCode ! AND dic_code #{dicCode} /if if testkeyword ! null and keyword ! AND garbage_name LIKE CONCAT(%, #{keyword}, %) /if /where ORDER BY create_time DESC /selectwhere标签会自动去掉首个多余的AND不用手写11。CONCAT(%, #{keyword}, %)用#{}预编译而不是${}能防 SQL 注入——这是答辩老师最常追问的安全点。分页在 Service 里PageHelper.startPage(pageNum, pageSize)紧跟查询方法返回PageInfo给前端里面带total、list、pages前端分页组件直接吃。注意PageHelper.startPage必须写在真正执行查询的那一行之前中间不能隔其他查询否则分页会作用到错误的 SQL 上。3.3 文件上传与图片回显的目录约定垃圾分类信息、公告都可能带图片。上传接口统一放FileController落地到服务器本地目录或项目外挂目录数据库只存相对路径。PostMapping(/upload) public Result upload(RequestParam(file) MultipartFile file) { String ext file.getOriginalFilename() .substring(file.getOriginalFilename().lastIndexOf(.)); String fileName UUID.randomUUID().toString().replace(-, ) ext; File dest new File(uploadPath File.separator fileName); if (!dest.getParentFile().exists()) { dest.getParentFile().mkdirs(); // 目录不存在则创建避免首次上传失败 } file.transferTo(dest); return Result.ok(/upload/ fileName); // 返回可访问相对路径 }用 UUID 重命名而不是原始文件名避免中文名、重名覆盖和安全问题。Spring Boot里还要配spring.servlet.multipart.max-file-size默认 1MB 传张手机照片就超了改成10MB是常规操作。返回相对路径而不是绝对路径换了部署机器前端也不用改。4. 启动报错、时区与 SQL 兼容的排错清单4.1 启动阶段的高频错误定位第一类报错是DataSource初始化失败多数是application.yml里的密码、库名或时区参数不对先看控制台Communications link failure后面跟的 host 和 port。第二类是mapper-locations路径没写对导致Invalid bound statement (not found)检查 XML 是否真被打进target/classes/mapperIDEA 里有时需要mvn clean重编。第三类是端口占用Web server failed to start. Port 8080 was already in use改端口或杀进程都行。# 快速定位 8080 占用进程Windows netstat -ano | findstr :8080 taskkill /PID 进程号 /F # Linux / Mac lsof -i:8080 kill -9 PID排错顺序建议是先看最下面那段Caused by它才是根因上面那些只是异常链包装。很多同学复制到一半的报错去搜搜到的是表层的APPLICATION FAILED TO START白费时间。4.2 时区、字符集与连接参数的坑MySQL 5.7 加mysql-connector-java8.x 驱动时serverTimezone不配会在连接时就抛The server time zone value xxx is unrecognized。连接串里补齐useUnicodetruecharacterEncodingutf8否则中文垃圾名称入库变问号。建表统一utf8mb4配合utf8mb4_general_ci比utf8多支持 emoji用户留言里发个表情不会报错。报错现象大概率原因处理方式时间差 8 小时未设 serverTimezone连接串加serverTimezoneAsia/Shanghai中文变问号字符集不统一库表连接串全部 utf8mb4收藏出现重复行缺联合唯一索引加uk_user_garbage分页数据错乱startPage 位置不对紧贴查询方法调用4.3 前后端联调的跨域与接口约定Vue 开发服务器和 Spring Boot 不同端口浏览器会拦CORS。开发期在 Controller 或全局配置里开CrossOrigin或者用 vite / vue-cli 的 devServer 代理转发生产环境同域部署就没这问题。Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOriginPattern(*); // 开发期放开上线收紧到具体域名 config.addAllowedHeader(*); config.addAllowedMethod(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }setAllowCredentials(true)和addAllowedOrigin(*)在旧版本里会冲突用addAllowedOriginPattern(*)才不报错。上线前把这个换成前端实际域名安全指标那栏答辩时才有话讲。5. 改造论文模板与二次扩展的实用套路拿到这份论文加源码最省力的二次改造不是重写功能而是改业务语义。把垃圾换成药品器材图书表名和字段名不用大动只需替换字典表里的分类项和前端文案一套前端后台直接复活成一个全新的毕设题目。这个思路在热搜里springboot vue 前后端分离的讨论中也常被提到——分层清晰的项目换皮成本极低。具体做法是保留controller / service / mapper三层不动只动entity的字段注释和字典初始化 SQL。把分类下拉的初始数据写进data.sql用spring.sql.init.modealways在启动时灌入-- data.sql字典初始化改这里就能换掉整套业务分类 INSERT INTO dictionary (dic_code, dic_name, code_index, remark) VALUES (RECYCLE, 可回收物, 1, 纸张塑料金属等), (HARMFUL, 有害垃圾, 2, 电池灯管药品等), (KITCHEN, 厨余垃圾, 3, 剩菜剩饭果皮等), (OTHER, 其他垃圾, 4, 难以回收的废弃物);验证改造是否成功只要看新分类下能否正常新增垃圾、前端二级联动是否跟着变、收藏和留言是否仍挂在正确的garbage_id上。再进一步就是加积分字段投放记录表加points用户表加total_points每次管理员审核投放记录时累加排行榜用一条GROUP BY user_id ORDER BY SUM(points) DESC就能出来。这一步做完系统从纯 CRUD 变成有业务闭环的作品答辩时讲积分激励比讲增删改查有说服力得多。还有一个细节值得抠论坛帖子和留言板都存内容但论坛要支持板块和标题建议论坛单独一张forum表带section_code留言板用极简的message表。查询时各走各的索引别用type字段硬合并——合并后按类型过滤的查询在数据量上千后会明显变慢这是可扩展性指标最实在的落点。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门