简介面向高校计算机相关专业毕业设计、课程设计与期末大作业场景这套城市垃圾分类回收管理系统源码数据库整合包提供从前端页面到后端服务、数据库脚本的完整方案。后端采用 Java 技术栈前端包含 HTML、CSS、JavaScript并配有大量 GIF 操作演示便于理解垃圾分类、回收点管理、用户积分等核心业务逻辑。资源共 218 个文件包含 52 个 Java 源码、28 个 JS 交互脚本、17 个 HTML 页面、9 个 CSS 样式同时提供 SQL 数据库脚本与 Maven 配置压缩包仅 2.43MB轻量易部署。目前已有 209 人学习下载适合需要快速搭建高分毕设项目的同学参考。资源中附带 SQL 数据库脚本与 yml 配置文件源码和静态资源按目录清晰划分方便导入开发工具二次修改既可作为毕业设计答辩演示也能改造成小区垃圾分类监管平台或课程设计作品。1. 一份Java垃圾分类管理系统源码压缩包里到底装了什么拿到“Java城市垃圾分类回收管理系统源码数据库毕业设计.zip”这个压缩包很多人第一反应是解压后直接跑起来看页面。但作为IT从业者看到这个标题更应该清楚它代表的是Java Web开发里最典型的一条交付链路源码、数据库脚本、配置文件打包进一个zip交给别人部署。系统本身要解决的业务问题很具体居民知道垃圾该扔进哪个桶回收人员能接到上门回收订单后台能看到各小区回收量。技术点也正好覆盖Java基础面试题里高频出现的枚举、事务、关联查询和分页。我按自己跑通同类项目的顺序用Spring Boot 2.x MyBatis MySQL 8.0组合把解压zip、导入数据库、改参数、验证核心功能的完整路径讲清楚。适合正在做java课程设计或接手遗留源码的开发者。2. 分解垃圾分类回收管理系统的表结构从zip里的SQL脚本看数据库设计系统里真正决定业务边界的是数据库表。很多人在源码里写了一大堆Controller却立不住因为表结构没有围绕“人-小区-垃圾桶-分类记录-积分”这条主线展开。我一般先看zip里附带的.sql脚本如果没有单独脚本就从application.yml里找到mapper目录下的建表语句。以MySQL 8.0为例表设计会集中在以下七张表community、garbage_user、trash_bin、waste_category、waste_record、recycle_order、points_log。字符集统一使用utf8mb4排序规则用utf8mb4_unicode_ci这样投放备注里的生僻字不会被截断。2.1 用户、小区与垃圾桶基础表如何支撑多小区部署用户体系不需要一上来就接微信登录。毕业设计源码里最常见的是用一个garbage_user表保存手机号、所属小区和积分余额。先用小区把数据隔离起来再谈角色权限。CREATE DATABASE IF NOT EXISTS garbage_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE garbage_system; CREATE TABLE community ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, name VARCHAR(64) NOT NULL COMMENT 小区名称, address VARCHAR(128) NOT NULL DEFAULT COMMENT 地址, admin_phone VARCHAR(20) DEFAULT NULL COMMENT 负责人电话, longitude DECIMAL(10,6) DEFAULT NULL COMMENT 经度, latitude DECIMAL(10,6) DEFAULT NULL COMMENT 纬度, created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间 ) ENGINEInnoDB COMMENT小区表; CREATE TABLE garbage_user ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, community_id BIGINT NOT NULL COMMENT 所属小区, open_id VARCHAR(64) DEFAULT NULL COMMENT 微信openid, phone VARCHAR(20) NOT NULL COMMENT 手机号, balance_points INT NOT NULL DEFAULT 0 COMMENT 剩余积分, status TINYINT NOT NULL DEFAULT 1 COMMENT 0禁用 1正常, created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间, KEY idx_community (community_id) ) ENGINEInnoDB COMMENT居民用户表; CREATE TABLE trash_bin ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, community_id BIGINT NOT NULL COMMENT 所属小区, bin_type TINYINT NOT NULL COMMENT 1可回收 2有害 3厨余 4其他, code VARCHAR(32) NOT NULL COMMENT 垃圾桶编号, location_desc VARCHAR(128) DEFAULT NULL COMMENT 位置描述, capacity_kg DECIMAL(8,2) NOT NULL DEFAULT 100.00 COMMENT 额定容量kg, last_clear_time DATETIME DEFAULT NULL COMMENT 最近清运时间, KEY idx_community_type (community_id, bin_type) ) ENGINEInnoDB COMMENT垃圾桶表;建表时的几个参数值得说明DECIMAL(10,6)存经纬度计算“附近回收点”时精度足够同时避免用DOUBLE的浮点误差手机号字段用VARCHAR(20)而不是BIGINT因为前端表单可能传进来86前缀BIGINT转换会直接报错。垃圾桶表里的bin_type用TINYINT配合waste_category字典表解释含义不要直接在业务表里写中文否则后面做统计和扩展都费劲。在设计garbage_user时status字段的默认值必须为1避免注册逻辑漏设状态导致新用户无法登录。community_id加普通索引就够不用建唯一索引因为一个小区可以有多个用户。2.2 垃圾类别、投放记录与积分流水核心业务表的关联关系垃圾分类业务需要四张表相互配合。waste_category是字典表存四分类waste_record是事实表存一次投放行为points_log是流水表存积分变动recycle_order处理上门回收订单。CREATE TABLE waste_category ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, category_name VARCHAR(16) NOT NULL COMMENT 四分类名, recycle_ratio DECIMAL(4,2) NOT NULL DEFAULT 1.00 COMMENT 积分倍率, icon_url VARCHAR(255) DEFAULT NULL COMMENT 图标地址, sort_no INT NOT NULL DEFAULT 0 COMMENT 排序号 ) ENGINEInnoDB COMMENT垃圾类别字典表; CREATE TABLE waste_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, user_id BIGINT NOT NULL COMMENT 投放人, bin_id BIGINT NOT NULL COMMENT 垃圾桶, category_id BIGINT NOT NULL COMMENT 垃圾类别, image_url VARCHAR(255) DEFAULT NULL COMMENT 现场照片, weight_kg DECIMAL(8,3) NOT NULL COMMENT 投放重量kg, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待审核 1有效 2无效, created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 投放时间, KEY idx_user_time (user_id, created_time), KEY idx_category_time (category_id, created_time) ) ENGINEInnoDB COMMENT垃圾投放记录表; CREATE TABLE points_log ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, user_id BIGINT NOT NULL COMMENT 用户, record_id BIGINT NOT NULL COMMENT 关联业务记录, change_points INT NOT NULL COMMENT 变动值, points_type TINYINT NOT NULL COMMENT 1投放奖励 2兑换扣减 3签到, remark VARCHAR(128) DEFAULT NULL COMMENT 备注, created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 变动时间, KEY idx_user (user_id) ) ENGINEInnoDB COMMENT积分流水表;这组表结构的核心在索引。idx_user_time让投递记录的“用户时间”范围查询走索引后台查询“某用户最近一个月扔了多少次”时不会全表扫描idx_category_time用来支持按类别汇总统计可回收物回收量时直接按category_id分组。points_log里的record_id虽然关联waste_record但并不建外键约束这是MySQL在线业务里常见做法保留逻辑关联避免外键带来的插入锁开销。如果要恢复数据可以用JOIN查询但分页时先查主表再关联流水避免驱动表太大。每个分类的回收积分如何定建议在waste_category里增加recycle_ratio字段而不是硬编码。比如厨余垃圾积分倍率0.5可回收物1.0有害垃圾0这样后台运营人员可以通过一个数据库更新操作调整规则而不需要改代码重新部署。2.3 初始化数据SQL让页面启动后有内容可看只有空表结构系统登录后什么都看不到。一个可演示的数据库至少要有四类垃圾字典、一个小区、两个测试用户和几条投放记录。初始化脚本如下INSERT INTO waste_category (category_name, recycle_ratio, sort_no) VALUES (可回收物, 1.00, 1), (有害垃圾, 0.00, 2), (厨余垃圾, 0.50, 3), (其他垃圾, 0.20, 4); INSERT INTO community (name, address) VALUES (锦绣小区, 滨河路128号); INSERT INTO garbage_user (community_id, phone, balance_points, status) VALUES (1, 13800001111, 100, 1), (1, 13900002222, 20, 1); INSERT INTO waste_record (user_id, bin_id, category_id, weight_kg, status) VALUES (1, 1, 1, 2.500, 1), (2, 2, 3, 1.200, 1);初始化参数说明有害垃圾的倍率设为0因为这类垃圾不应给居民积分避免系统被误用成积分刷分入口。测试账号的密码字段没有在上面的INSERT里出现因为生产环境应该用BCrypt存储开发阶段可以先使用固定的加密串不要在SQL里直接写明文密码。这里故意只写了少量初始化记录后续测试分页和统计时再通过业务接口造数据这样能验证新增逻辑是否真的写入数据库。插入完成后用一条统计SQL检查数据能否正确关联SELECT c.category_name, COUNT(r.id) AS cnt, ROUND(SUM(r.weight_kg), 2) AS total_kg FROM waste_record r JOIN waste_category c ON r.category_id c.id GROUP BY c.category_name;这条SQL把投递记录按类别分组统计条数和总重量是垃圾分类管理后台最常用的查询之一。如果返回结果为空先检查waste_record里是否有外键连接错误。关联查询时注意表别名要清晰避免在后期增加join条件时出现字段歧义。3. 从zip解压到Spring Boot启动把数据库和源码真正跑通拿到压缩包后先别急着双击很多问题都出在解压阶段。标题里的.zip既是分发格式也是最容易被忽略的故障点。常见做法是在Linux上使用unzip命令在Windows上使用7-Zip或自带资源管理器但无论用哪种方式解压后要立刻检查目录层次避免出现“压缩包里套同名文件夹”的情况那会让后续的路径配置全部偏移。3.1 解压zip并识别项目类型先执行下面的命令把项目解压到单独目录unzip Java城市垃圾分类回收管理系统源码数据库毕业设计.zip -d garbage-system cd garbage-system ls -la参数说明-d指定解压目标目录防止文件散落在当前目录ls -la可以看到项目根目录内容。如果unzip命令提示“command not found”在Debian系系统上执行apt install unzip安装在CentOS上执行yum install unzip。Windows环境没有unzip命令可以把7-Zip的7z.exe加入PATH然后使用7z x 文件名.zip -ogarbage-system。无论用哪种方式目标目录应直接出现pom.xml或build.gradle如果有classes目录和SQL脚本但没有pom.xml说明这是一份只编译未打包的产物后续需要先还原项目结构。常见的项目结构长这样garbage-system/ ├── pom.xml ├── src/main/java/com/garbage/ ├── src/main/resources/application.yml ├── src/main/resources/mapper/*.xml ├── sql/garbage_system.sql └── README.md从这个结构能看出项目基于Maven管理依赖数据库脚本独立放sql目录Mapper XML和配置文件都在resources下。如果script目录出现的是.sql和.db文件并存不要直接复制.db文件数据库文件是二进制格式和本机MySQL版本可能不匹配正确做法是只导入.sql脚本。3.2 检查JDK、Maven和MySQL版本是否匹配在运行之前把环境变量配置检查一遍。很多java课程设计项目在运行时报ClassNotFoundException或UnsupportedClassVersionError都是版本不匹配造成的。java -version mvn -v mysql --version版本匹配的参考组合见下表组件推荐版本常见问题JDK8 / 11JDK 17跑Spring Boot 2.x会有兼容问题Maven3.6.3老版本无法下载新版依赖MySQL5.7 / 8.08.0需要显式指定时区和驱动Spring Boot2.7.x与JDK 8搭配最稳参数说明JDK 8是Spring Boot 2.x最主流的运行环境如果本机同时装了多个JDK在IDEA里Project Structure切到对应版本在命令行用JAVA_HOME指定路径。MySQL 8.0默认认证插件是caching_sha2_password老版驱动连接时会报Public Key Retrieval is not allowed需要把驱动升级到mysql-connector-java 8.0.33以上同时在JDBC URL中加allowPublicKeyRetrievaltrue。查看项目的Spring Boot版本可以执行mvn help:evaluate -Dexpressionproject.parent.version -q -DforceStdout输出显示的版本号会直接决定JDK选择。如果显示3.x本机必须安装JDK 17如果是2.xJDK 8或11都能用。3.3 导入数据库脚本与修改数据源参数数据库结构已经在前一章建好。如果zip里的sql脚本自带建库语句直接执行mysql -u root -p -f sql/garbage_system.sql参数说明-f表示遇到SQL错误继续执行适合首次导入时跳过重复建表错误。如果脚本里没有CREATE DATABASE语句需要手动先建库再把sql文件导进去。导入后立刻检查表数量和字符集USE garbage_system; SHOW TABLES; SELECT character_set_database;如果查询结果里所有中文都是问号说明导入时客户端字符集不对。重新执行导入并指定字符集mysql -u root -p --default-character-setutf8mb4 sql/garbage_system.sql然后修改项目的application.yml。绝大多数源码都通过Spring Boot的配置文件读取数据库连接位置在src/main/resources/application.ymlspring: datasource: url: jdbc:mysql://localhost:3306/garbage_system?useUnicodetruecharacterEncodingutf8mb4serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: root password: 你的密码 driver-class-name: com.mysql.cj.jdbc.Driver servlet: multipart: max-file-size: 10MB max-request-size: 20MB mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.garbage.entity logging: level: com.garbage.mapper: DEBUG这里的参数值得逐项说明characterEncodingutf8mb4保证中文正常读写serverTimezoneAsia/Shanghai防止JDBC与MySQL时区不一致导致时间字段偏移8小时useSSLfalse跳过本地环境无用的加密握手减少警告。multipart段控制文件上传大小垃圾分类系统里的现场照片通常在3MB以内10MB足够。mybatis.mapper-locations指定XML文件位置如果路径写错启动时只会报“Invalid bound statement”不看到这一层很容易去翻Java代码。生产环境不要直接把密码写进yaml用环境变量覆盖是更安全的做法SPRING_DATASOURCE_PASSWORD你的密码 mvn spring-boot:runSpring Boot启动时会读取这个环境变量并覆盖yaml中的默认值这样配置文件可以提交到仓库而密码只保留在部署机器上。3.4 使用Maven打包并启动应用数据库导入成功后就可以编译启动。最小步骤是mvn clean package -DskipTests java -jar target/garbage-system-0.0.1-SNAPSHOT.jar --server.port8080参数说明clean先删除旧target目录package把项目打成可执行jar包-DskipTests跳过测试减少环境干扰。如果项目里使用了Lombok要确保JDK版本与Lombok版本兼容否则编译会报“java: package lombok does not exist”这时需要在pom.xml里把lombok.version升级到支持当前JDK的版本。启动日志出现“Started XxxApplication in xx seconds”后用浏览器访问http://localhost:8080。在服务器上部署时通常把日志重定向到文件并放到后台运行nohup java -jar target/garbage-system-0.0.1-SNAPSHOT.jar app.log 21 nohup让java进程不随SSH会话断开而退出 app.log把控制台输出写入文件21把错误输出也合并到同一个文件。等两分钟后查看app.log如果看到“Tomcat started on port(s): 8080”系统已启动完毕。如果端口被占用改用--server.port8081或者修改配置文件。检查端口监听状态可以用ss -lntp | grep 8080这一步能快速确认端口是否真的被Java进程监听。Windows环境下即使启动成功也没有页面大概率是防火墙拦截了8080端口在控制面板入站规则里放行即可。4. 核心业务实现垃圾分类识别、积分扣减与接口验证数据库和启动跑通后真正要改代码时才需要重点看业务逻辑。这个系统里的垃圾分类识别和积分扣减是两端最容易出问题的地方。我在写类似系统时会先定义枚举和接口再实现Service少写if else避免功能越加越乱。4.1 用枚举替代if else完成垃圾类别识别“报纸是什么垃圾塑料瓶是什么垃圾”这类需求如果在Controller里用if判断后面加一个分类就要改一次代码。更常见且好维护的做法是把类别定义成枚举配合关键词集合做匹配。public enum WasteCategory { RECYCLABLE(1, 可回收物, Arrays.asList(报纸, 塑料瓶, 玻璃瓶, 易拉罐)), HAZARDOUS(2, 有害垃圾, Arrays.asList(电池, 温度计, 油漆桶)), KITCHEN(3, 厨余垃圾, Arrays.asList(剩饭, 菜叶, 果皮)), OTHER(4, 其他垃圾, Arrays.asList(卫生纸, 陶瓷碎片)); private final Integer code; private final String name; private final ListString keywords; WasteCategory(Integer code, String name, ListString keywords) { this.code code; this.name name; this.keywords keywords; } public Integer getCode() { return code; } public String getName() { return name; } public static Integer matchByName(String keyword) { if (keyword null || keyword.isBlank()) { return OTHER.getCode(); } for (WasteCategory category : WasteCategory.values()) { for (String item : category.keywords) { if (keyword.contains(item) || item.contains(keyword)) { return category.getCode(); } } } return OTHER.getCode(); } }逻辑说明枚举里的keywords只保留了演示用的少量垃圾名词实际项目建议把关键词放进数据库字典表方便后台运营在线维护。matchByName方法先用空值判断兜底再遍历每个类别的关键词用双向contains判断是为了兼容用户输入“一个塑料瓶”和“塑料瓶”都能命中。注意isBlank是JDK 11才有的方法如果项目编译目标是JDK 8应改用keyword.trim().isEmpty()否则javac会直接编译失败。这里的降级返回OTHER保证前端收到的是一个合法类别code。在Service里调用枚举并同时插入一条投放记录Service public class WasteRecordService { Resource private WasteRecordMapper wasteRecordMapper; Transactional(rollbackFor Exception.class) public Integer submitWasteRecord(Long userId, Long binId, String keyword, BigDecimal weightKg) { Integer categoryCode WasteCategory.matchByName(keyword); WasteRecord record new WasteRecord(); record.setUserId(userId); record.setBinId(binId); record.setCategoryId(categoryCode); record.setWeightKg(weightKg); record.setStatus(0); wasteRecordMapper.insert(record); return categoryCode; } }Transactional(rollbackFor Exception.class)在这里是必须的insert过程中如果数据库连接断开或主键冲突整个方法会回滚不会给用户留下一条残废记录。只写Transactional可能回滚不掉CheckedException这也是Java面试题里经常追问的知识点。wasteRecordMapper.insert使用MyBatis生成的主键回填insert后record.getId()就是新的主键值后面记录积分流水时需要用到。4.2 积分扣减的乐观锁写法与积分流水记录回收预约订单通常需要扣减积分或用积分兑换礼品。如果直接SELECT余额然后在Java里扣减再UPDATE回去在并发请求下会出现超扣。常见做法是把余额判断放进UPDATE语句的WHERE条件中用数据库行锁保证原子性。Mapper方法Update(UPDATE garbage_user SET balance_points balance_points - #{points} WHERE id #{userId} AND balance_points #{points}) int deductPoints(Param(userId) Long userId, Param(points) Integer points);这条SQL的执行逻辑是只有用户剩余积分不小于扣减数时才会更新否则受影响行数为0。扣减成功后再插入一条积分流水Service public class PointsService { Resource private UserMapper userMapper; Resource private PointsLogMapper pointsLogMapper; Transactional(rollbackFor Exception.class) public boolean deductIfEnough(Long userId, Integer points, Long orderId) { int rows userMapper.deductPoints(userId, points); if (rows 0) { return false; } PointsLog log new PointsLog(); log.setUserId(userId); log.setRecordId(orderId); log.setChangePoints(-points); log.setPointsType(2); log.setRemark(回收预约积分抵扣); pointsLogMapper.insert(log); return true; } }参数说明deductPoints返回的rows是数据库更新的行数不是积分余额。rows 0时直接return false表示本次扣减无效调用方可以在Controller里返回“积分不足”。在同一个事务里先UPDATE后INSERT能保证余额与流水的最终一致性。如果先INSERT流水再UPDATE余额一旦余额不足流水虽然可以删除但在高并发下容易留下痕迹。注意不要在扣减前再执行一次SELECT余额做判断因为两次请求之间数据可能已经变化还是以UPDATE的影响行数为准。4.3 分页查询与接口验证用Swagger或Postman快速跑通源码里如果只有零散的HTTP接口项目很难交付。建议统一接口风格把查询参数包装成对象RestController RequestMapping(/api/waste) public class WasteRecordController { Resource private WasteRecordService wasteRecordService; GetMapping(/list) public PageResultWasteRecord list(RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size, Long userId) { return wasteRecordService.pageQuery(page, size, userId); } }分页使用PageHelper时有一句话要记住PageHelper.startPage必须紧跟在要分页的查询语句前不能间隔其他数据库操作。错误示范是startPage后先执行了用户查询再执行投放记录查询分页会把两次查询都拦截导致返回List的size不对。public PageResultWasteRecord pageQuery(Integer page, Integer size, Long userId) { PageHelper.startPage(page, size); ListWasteRecord records wasteRecordMapper.selectByUserId(userId); PageInfoWasteRecord pageInfo new PageInfo(records); return PageResult.of(pageInfo); }PageInfo的total来自MyBatis的COUNT查询和List.size()是两回事。在返回给前端时total一定要用PageInfo.getTotal()否则前端无法正常渲染总页数。系统启动后使用Postman或直接浏览器验证这几个接口接口方法请求参数预期返回/api/waste/listGETpage1size10userId1投放记录分页/api/waste/submitPOSTbinId1keyword塑料瓶weightKg0.8返回垃圾分类code1/api/points/deductPOSTuserId1points10orderId1001true或false/api/points/logGETuserId1page1size10积分流水列表如果submit接口返回的code是1说明“塑料瓶”命中了可回收物枚举如果返回4则检查枚举里是否正确设置了keywords以及请求参数是否带有不可见字符。验证时可以在application.yml里把日志级别调成DEBUG看到MyBatis打印的SQL参数就能定位是数据库问题还是业务逻辑问题。5. 交付用来演示的细节乱码检查、zip伪加密与最终打包跑通只是第一步让系统“拿给别人也能正常运行”需要再做几件事。这部分的技巧不是代码功能而是工程习惯。我把它们按检查顺序放在最后每条都能在五分钟内验证。5.1 用一条curl命令验证接口编码和健康状态启动后用curl发起请求如果返回的中文变成\uXXXX的转义序列说明Jackson序列化配置没有强制UTF-8。在application.yml中增加spring: http: encoding: force: true再验证一次curl -s http://localhost:8080/api/waste/list?page1size10 | head -c 200看到中文正常显示就说明编码链路通了。如果数据库里的中文都正常但接口返回乱码通常是JDBC URL缺少characterEncodingutf8mb4或者Tomcat默认字符集不是UTF-8。5.2 识别zip伪加密和压缩包异常很多人收到源码zip后双击竟然要求输入密码而README没有写密码这很可能是“zip伪加密”现象。ZIP格式在文件头的通用位标记里有一位表示加密伪加密是这一位置被修改为1实际数据并没有真正加密。在Linux下查看zip详情zipinfo -v 文件名.zip | grep -i encrypt如果输出显示“file encryption: none”但解压时仍提示输入密码说明这是伪加密可以用7-Zip打开并选中文件如果右侧显示“Encrypted”为灰色即可确认。常见做法是使用zip工具修复目录或重新压缩。需要说明的是这里讨论的是压缩包格式异常不是破解密码遇到真正加密的zip正确做法是联系交付方获取密码。类似问题也常出现在数据库同步软件生成的包中来源不明的数据库文件建议先隔离环境再导入。5.3 调整HikariCP连接池参数源码里的默认连接池参数可能不适合演示机器。在并发演示时如果频繁报“Connection is not available, request timed out”需要调整连接池配置spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000maximum-pool-size控制最大连接数本地演示一般20足够connection-timeout是获取连接的超时时间单位毫秒30000表示30秒内拿不到连接就报错idle-timeout是空闲连接存活时间超过后被回收。调试时如果启动很慢建议把minimum-idle调小到1避免空闲连接占用MySQL进程。5.4 制作规范的zip交付包最后一步是重新打包把编译产物和本机日志排除在外zip -r final_submission.zip . -x target/* -x .git/* -x *.log -x *.db参数说明-x后面依次排除target目录、git元数据、日志文件和数据库文件。这样生成的新压缩包里只保留源码、SQL脚本和配置文件。打包完成后把它解压到另一个干净目录删除本地target目录再执行mvn spring-boot:run验证一遍。如果这次能正常起来说明交付包不依赖环境残留文件。更稳妥的做法是在zip里放入README.md注明JDK版本、MySQL版本、数据库账号和默认管理员密码。这样做能避免拿到zip的人反复猜测配置。最后把生成的zip重命名成“Java城市垃圾分类回收管理系统源码数据库毕业设计.zip”时要注意压缩包内不要包含绝对路径例如“C:\Users...”这类信息否则在另一台机器解压会看到一大堆空目录。本文还有配套的精品资源点击获取