基于SpringBoot的闲置物品循环利用管理系统设计与实现
每年到这个时间点总会有一批同学盯着“计算机毕业设计选题”发愁。今年问我最多的一个题目是“基于SpringBoot的闲置物品循环利用管理系统”有的学校叫“旧物回收商城”也有叫“二手物品交易与捐赠平台”。名字好几个内核其实就一个让用户把手里闲置的东西挂出来给别人买走或者直接捐出去平台负责撮合、记录和审核。这个题目属于典型的SpringBoot全栈项目技术栈不偏门、业务链路清晰、可发挥的点多不管是毕业设计、课程设计还是自己练手都值得认真做一遍。这篇文章我从选题拆解、功能规划、数据库设计、核心流程实现到开发中容易踩的坑、答辩常见提问一次性讲透。1. 项目定位与核心需求拆解1.1 这个系统到底要解决什么问题先想清楚一点你这个题目不是要做成电商平台也不是要做成闲鱼式的大型C2C社区。它的核心定位是“校园级/社区级的闲置物品循环利用平台”用户量不大业务链路要完整功能不必冗余到支付分账、物流跟踪、信用体系那一层。被这个题目卡住的同学大多卡在同一个地方——不知道“二手交易”和“捐赠”两条线怎么在同一个系统里组织。这里先把业务模型说清楚普通商品交易链路用户发布闲置商品 → 审核上架 → 买家浏览下单 → 模拟支付 → 卖家发货 → 买家确认收货 → 订单完成。捐赠物资链路用户发布捐赠物品 → 审核公示 → 有需要的人提出申请 → 发布者确认 → 线下自提或平台虚拟交付 → 生成捐赠记录。两条链路共用一套用户体系、商品发布体系、后台审核体系但是订单状态和物资流转方式完全不同。这个“两线并行”的设计如果一开始想明白了后面数据库和接口设计都会顺畅很多。1.2 功能模块的边界划分建议按角色拆别按“交易”和“捐赠”拆不然代码结构会乱。角色就三个普通用户、管理员、游客未登录用户。游客只能浏览注册登录后才能操作。端侧功能点说明用户端注册登录、个人中心用户名密码不要搞复杂登录用户端商品发布、编辑、下架支持图片上传、分类选择、成色描述用户端商品搜索、分类筛选按关键词、分类、价格区间筛选用户端商品详情、收藏方便二次浏览用户端下单购买地址选择、模拟支付用户端发布捐赠、申请领取申请需填写用途说明用户端订单管理、捐赠记录查看自己买到的、卖出的、捐出的管理端用户管理禁用/启用账号管理端商品审核审核上架、强制下架管理端捐赠审核审核捐赠申请、确认完成管理端数据统计商品数量、订单量、捐赠数量、用户增长功能不在多在链路完整。你能把交易和捐赠两条链路各跑通一遍再把后台审核串起来这个系统就已经超过大多数选了类似题目的同学了。1.3 哪些功能建议做成亮点毕设想拿高分不能只做CRUD四个字母。建议在常规功能里突出几个点第一商品状态机设计。一个商品从发布到完成交易状态会经历“待审核 → 上架中 → 已被锁定 → 已售出”或者“上架中 → 已下架”。很多同学用字符串存状态状态一多就乱。我建议用int枚举值配合一个状态流转工具类代码干净答辨时也讲得清楚。第二捐赠公示功能。捐赠完成后在首页或者独立页面展示“xxx于x月x日捐赠了xx物品由xx签收”。这一步看似简单却能体现你的业务思考——公益行为需要公开透明这在系统设计里是有真实价值的。第三绿色积分或环保值。每完成一笔闲置交易或捐赠给用户累加积分个人中心显示累计减少碳排放或节约资源的数据。不一定精确但作为激励用户使用的机制答辩时是亮点。2. 技术选型为什么是SpringBoot而不是SSH/SSM2.1 后端选型分析现在毕设环境里SpringBoot已经是事实标准为什么最核心的原因就是“开箱即用”。以前用SSM光是Spring、SpringMVC、MyBatis三个框架的xml配置文件就要写一大堆版本兼容问题能把人磨掉一层皮。SpringBoot用自动配置把这些问题全部压下去你只需要专注写业务代码。如果你是在校学生对这点的理解可以再进一步SpringBoot默认集成内嵌Tomcat项目打包成jar就能跑。演示的时候在答辩教室的电脑上只要装了JDK一行命令就能启动不需要额外配置外部Tomcat这对毕设演示是一个巨大的优势。换成SSH框架老项目依赖一堆XML配置换个环境还得调JDK版本、Tomcat版本出问题以后现场很难收场。2.2 前端与前后端分离前端我推荐Vue 3 Element Plus Vite。Element Plus本身是现成的后台管理组件库一套页面搭起来非常快。你要是对Vue不熟就用Vue 2也行但既然是新项目建议直接用Vue 3版本新一点简历上写出去也不显得陈旧。前后端分离以后开发模式是后端只提供JSON接口前端通过axios调用。这里有一个常见误区很多同学一开始喜欢用模板引擎写服务端渲染页面比如直接用Thymeleaf把页面和后端耦合在一起。不是说不能用而是如果做毕设前后端分离会让你的项目结构更清晰方便你分模块写论文。答辩老师看见你有独立的前端工程目录、有接口统一封装会觉得你具备工程化意识。接口路径建议统一以/api开头例如/api/product/list、/api/order/create。这样在nginx部署或后端统一拦截权限时一个前缀就能覆盖所有需要鉴权的接口。2.3 存储与中间件的取舍数据库用MySQL这个不用多考虑。ORM层建议用MyBatis-Plus不是纯粹的原生MyBatis。原因很简单MyBatis-Plus有现成的BaseMapper、LambdaQueryWrapper、分页插件单表查询基本不用写SQL可以省下大量时间。除非你的查询特别复杂否则尽量别写一堆XML里的动态SQL。文件存储这里要慎重。如果你选云存储比如阿里云OSS需要注册账号、创建Bucket、配置密钥对于很多同学来说卡在开通流程上就能耗掉一整天。我建议本地存储起步后端配置一个上传目录把文件流写到磁盘再通过一个/upload/文件名的映射路径对外访问。后期如果项目要部署上线再替换成云存储也不难。Redis不是必选项。如果你已经会用Redis可以在首页轮播图、商品分类、热点商品上加缓存如果不会也不用强行加。不要为了显得高级把Session存到Redis里却连过期策略都说不清楚答辩时反而减分。2.4 版本锁定小技巧版本问题在毕设项目里最容易爆炸。SpringBoot 2.7.x和SpringBoot 3.x之间很多东西不兼容比如JDK版本要求、javax与jakarta命名空间、Spring Security的配置方式。我的建议很明确如果你JDK是8或11就选SpringBoot 2.7.x配MyBatis-Plus 3.5.x、MySQL 8.x如果你JDK是17及以上可以选SpringBoot 3.x但要确认MyBatis-Plus版本支持SpringBoot3。不要混合用不要随手复制网上的依赖版本最好用Spring Initializr直接生成基础工程再往里面加依赖。毕业设计不是为了演示“最新版本”而是要稳定跑通。组件推荐版本备注Spring Boot2.7.18稳定支持JDK8MyBatis-Plus3.5.3对应SpringBoot2MySQL8.08.0以上默认utf8mb4Vue3.x配Element PlusJDK1.8或112.x版本最高支持到173. 数据库设计与业务表结构3.1 表结构怎么梳理数据库设计是整个项目的根基后面接口写得好不好、逻辑顺不顺全看这一步。以这个系统为例建议先按“实体-关系”的思路思考有哪些核心实体用户、地址、商品、商品图片、商品分类、订单、订单明细、收藏、捐赠、捐赠申请、系统公告、审核记录。这些实体之间的典型关系是用户与商品一对多一个用户可以发布多个商品商品与分类多对一一个分类下有多个商品商品与图片一对多一个商品多张图用户与订单一对多一个用户可买可卖商品与订单通过订单明细建立关联用户与收藏多对多通过收藏表体现建议至少建下面这些表sys_user 用户表 sys_address 地址表下单时用 category 商品分类表 product 商品表 product_picture 商品图片表 orders 订单主表 order_item 订单明细表 favorite 收藏表 donation 捐赠物品表 donation_apply 捐赠申请表 message 站内信/留言表3.2 关键字段设计经验这里挑几个容易设计出错的关键字段重点说。第一个是金额字段。交易涉及的钱一律用DECIMAL(10,2)不要用double。二进制浮点数在做金额计算时会出精度问题虽然平时测试可能看不出来但一旦遇到校验给用户的金额显示就会出现0.30000000000000004这种恶心结果。用decimal后端Java实体对应BigDecimal前端展示时再格式化两位小数。第二个是状态字段。状态类型统一用TINYINT或INT不要用VARCHAR存“已上架”“已下架”这种中文。用int的好处是状态流转时可以直接比较数字而且以后扩展状态不涉及改表结构。比如商品状态0-待审核 1-上架中 2-已被锁定 3-已售出 4-已下架 5-审核拒绝订单状态同理0-待支付 1-已支付待发货 2-已发货 3-已完成 4-已取消 5-退款中第三是时间字段。创建时间、更新时间这种用create_time、update_time统一命名数据库类型datetime插入和更新时在后端代码里统一填充或者用MyBatis-Plus的自动填充注解TableField(fill FieldFill.INSERT)。千万别在数据库里建一堆time1、time2这种无意义字段名。第四是逻辑删除。不要物理删除用户发布过的商品用deleted字段标记0表示正常1表示已删除。这是因为订单、收藏、统计报表里都可能引用商品信息物理删除会把关联数据搞成孤儿。3.3 一段核心建表SQL示例商品表product的设计如下CREATE TABLE product ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, user_id BIGINT NOT NULL COMMENT 发布者ID, category_id BIGINT DEFAULT NULL COMMENT 分类ID, title VARCHAR(100) NOT NULL COMMENT 标题, description TEXT COMMENT 物品描述, price DECIMAL(10,2) DEFAULT NULL COMMENT 售价捐赠物品为NULL, is_donation TINYINT DEFAULT 0 COMMENT 0-普通出售 1-捐赠, status TINYINT DEFAULT 0 COMMENT 状态0待审核 1上架 2锁定 3售出 4下架 5拒绝, cover_image VARCHAR(255) DEFAULT NULL COMMENT 封面图, view_count INT DEFAULT 0 COMMENT 浏览量, version INT DEFAULT 0 COMMENT 乐观锁版本号, deleted TINYINT DEFAULT 0 COMMENT 逻辑删除, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_category_id (category_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT闲置物品表;这个表里比较大的亮点是is_donation字段与version字段。前者把“普通交易”和“捐赠”两种模式并到一张表用字段区分而不是拆两张表逻辑集中、代码好写。后者是给乐观锁预留的防止两个用户同时在秒杀场景下买到同一件仅剩一件的宝贝。3.4 订单与商品的关系别搞复杂很多同学喜欢把所有信息都塞进订单表比如订单里存商品标题、商品图片、卖家ID、买家ID、地址、金额、备注。这样做很爽因为查询订单时不用关联其他表但代价是数据冗余严重商品信息改了以后旧订单里的商品标题还是老的显示不一致。正确做法是订单主表只存业务级信息订单号、买家ID、卖家ID、总金额、状态、创建时间、支付时间。具体买了什么东西拆到订单明细表里明细表存商品ID、商品快照标题、商品快照图片、单价、数量。为什么强调“快照”因为商品下架或改价后订单里的历史信息不应该跟着变明细表里冗余一份当时的标题和图片反而是一种合理的做法。4. 核心流程实现二手交易与捐赠双链路4.1 商品发布到上架商品发布接口建议设计成两个阶段前端先上传图片拿到图片路径再把表单数据和图片路径一并提交到后端最后数据库里保存商品记录和图片记录。用户在前端点“发布闲置”后要填标题、分类、成色、价格、描述、上传图片。这里最基本的校验包括标题不能为空、长度不能超过100价格如果是出售物品必须大于0图片必须至少一张。后端Controller接收ProductDTO之后Service层的步骤是把DTO里的字段赋值到Product实体设置userId为当前登录用户ID设置status0表示待审核插入商品主表遍历图片列表逐一插入product_picture表返回商品ID写这个流程的时候注意一件事不要在前端把状态直接写成“上架”状态必须由后端管理员审核后才置为1。有些同学偷懒发布后直接上架审核机制整个没了那商品审核模块就白做了。4.2 买家下单与支付状态设计用户点击“立即购买”时前端跳转创建订单页选择地址确认金额后提交。后端创建订单的核心逻辑如下根据productId查商品校验商品状态是否为1上架中不是捐赠物品校验价格并计算总金额使用乐观锁或状态条件更新UPDATE product SET status 2, version version 1 WHERE id ? AND status 1如果更新影响行数为0说明商品被抢先下单或已下架直接返回“商品已售出或已锁定”创建订单主表记录状态为0待支付创建订单明细表这里必须强调一个关键设计商品状态从1变为2叫做“锁单”。如果你不做锁定支付过程中商品再次被别人下单就会一物多卖。把状态更新放到一条SQL里完成天然能防止并发超卖比在应用层if(product.getStatus()1)判断安全得多。模拟支付怎么做不要真的去接微信支付或支付宝申请商户号对于毕设来说不现实而且涉及营业执照。建议在支付接口里做一个“模拟支付成功”的路程前端点击支付按钮调用/api/order/pay后端验证订单属于当前用户且状态为0然后把订单状态改为1记录支付时间。也可以在页面上做一个小弹窗“确认支付本系统为模拟支付”看起来更真实。订单超时未支付怎么办如果没做定时任务一般就让它挂着演示时手动取消。但我建议做一个简单的延时释放用Spring自带的Scheduled定时任务每分钟扫描一次待支付订单超过30分钟未支付就把订单置为取消同时把对应商品状态从2改回1。加了这个功能商品释放的逻辑就完整了。4.3 捐赠流程怎么闭环捐赠是区分这个项目和普通商城的关键模块。业务上怎么设计呢第一步用户发布捐赠物品时前端多一个“选择捐赠”的开关。选中后价格字段隐藏描述里建议填物品使用情况、适合人群。数据库里is_donation1priceNULL状态同样先走待审核。第二步审核通过后商品在列表中展示但详情页不显示“购买”按钮而是显示“申请领取”按钮。申请领取时需要填申请理由或用途说明——这一点千万要保留。真实场景里公益物资要让给真正需要的人而不是谁手快谁拿走。第三步管理员在后台能看到捐赠申请列表结合申请理由可以选择“批准申请”或“拒绝申请”。同时发布者也能在自己的捐赠记录里看到谁申请了双方都可以确认。比较简单的做法是管理员批准后订单状态直接进入“待领取”或“已确认”然后由发布者线下交付物品再在系统里确认“已完成”。第四步捐赠完成后生成一条公开的捐赠记录展示捐赠物品名称、捐赠时间、领取人昵称脱敏处理不要展示真实姓名和手机号。这条记录放在首页“捐赠公示”模块让整个链路形成闭环业务上说得通答辩时也比较有料。捐赠流程的核心代码不会比普通交易复杂但很容易被做成“只有发布和删除”的半成品。如果你能把捐赠的“申请-审核-公示”三段式流程完整实现这个项目的完成度立刻就和别人拉开差距。4.4 商品详情接口要同时返回哪些内容商品详情页是核心聚合页面后端接口建议一次返回完减少前端多次请求。返回值可以包含商品基本信息标题、价格、状态、是否捐赠、描述、成色图片列表发布者信息昵称、信用积分、发布总数当前登录用户是否已收藏该商品如果是捐赠物品是否有待审核的申请记录Service层组合数据时用Map或专门写一个ProductDetailVO别把Entity直接返回给前端。因为Entity里可能有userId这种敏感字段你直接返回前端即使不显示抓包也能看到看着就不专业。5. 权限、安全与后台管理5.1 角色权限设计后台管理的账号也放进用户表加一个role字段用0-普通用户 1-管理员区分不用额外建一张角色表。如果你后续想扩展多角色比如运营、审核员再加sys_role、sys_user_role表也不迟。校验方式可以非常简单前端在路由守卫里根据当前用户的role判断能否进入管理端页面后端在每个管理接口上校验当前登录用户的role是否为1。不要只用前端隐藏按钮来防越权安全设计的底线是后端校验。还有一类越权特别容易被忽略普通用户把请求地址里的订单ID改掉去查看别人的订单详情。后端查询订单时必须判断订单的buyerId或sellerId是不是当前登录用户不是就返回无权限。这个逻辑写在Service里别只靠前端权限。5.2 登录状态与Token方案很多老教程还是SessionRedis的登录方案但实际开发中用JWT更常见。JWT本质上是一段自包含的加密令牌用户登录成功后后端返回一个token前端存到localStorage里之后每次请求放在请求头Authorization: Bearer token中。后端写一个拦截器对所有以/api/开头、但不是/api/user/login、/api/user/register等公开接口的请求进行token校验。校验通过后从token中解析出用户ID放到ThreadLocal或者请求属性里方便Service取用。JWT方案也有坑token过期后前端所有的接口都会报401用户体验不好。建议token有效期设为一个较长的时间比如7天或者做refresh_token机制。毕设没必要做得太重设7天并提示“重新登录”即可。5.3 密码存储不能明文所有系统都绕不开密码安全这个点几乎是答辩必问。直接存明文密码是最低级的做法。用BCrypt哈希处理Spring Security的BCryptPasswordEncoder可以直接用。BCrypt的特点是同一密码每次加密结果不同因为带随机盐数据库被拖走后也无法反向解析。注册接口的流程是前端把用户名密码传到后端后端使用BCryptPasswordEncoder.encode()加密后存库。登录时取出数据库里的哈希值调用.matches(rawPassword, encodedPassword)校验。因为JWT方案不需要依赖Spring Security的完整过滤器链你可以只引入spring-security-crypto包用它的加密工具不需要让整套Spring Security接管你的接口降低配置复杂度。5.4 管理端审核链路怎么设计后台管理端的商品审核页要支持列表和详情预览。列表建议分页展示所有status0的商品。点击“审核通过”后将status改为1点击“拒绝”后填写拒绝原因状态改为5。这里我建议加一个audit_record表记录谁在什么时候审核了哪个商品、结果是什么、备注是什么。这样做的好处有两个一是答辩时有一张能讲清楚的“链路表”体现你的系统考虑到了可追溯性二是商品被举报或纠纷时后台有据可查。审核记录表字段可以简单一点target_type表示对象类型商品/捐赠target_id表示对象IDuser_id审核人result结果remark备注create_time时间。6. 实际编码过程中的避坑点6.1 表名与字段名别踩保留字这个坑几乎每年都有人踩用户表想命名为user订单表想命名为order。但在MySQL里USER是系统表相关关键字ORDER也是SQL关键字直接使用会报错或者需要不停地加反引号非常痛苦。解决方法是表名统一加业务前缀比如sys_user、ord_orders或者直接用t_user、t_order这种命名风格。字段同理像desc、level、condition这些词能避开就避开改用description、user_level避免和SQL关键字冲突。6.2 MyBatis-Plus的更新策略坑用MyBatis-Plus时实体字段默认更新策略是对非空字段进行更新。也就是说前端传一个Product对象如果某个字段没填它就认为你不想更新这个字段不会把原来的值覆盖成NULL。这个机制在大多数时候是好事但如果你希望把某个字段设置为空或0就会更新不上去。比如要清空备注信息setRemarks(null)后调用updateById数据库里的值没变。解决的方法是在这些字段上加上注解TableField(updateStrategy FieldStrategy.NOT_NULL)默认策略保持非空更新但特殊的字段可以单独覆盖。或者也可以直接用UpdateWrapper手动设置字段LambdaUpdateWrapperProduct wrapper new LambdaUpdateWrapper(); wrapper.eq(Product::getId, productId) .set(Product::getStatus, 4) .set(Product::getUpdateTime, new Date()); productMapper.update(null, wrapper);6.3 日期格式返回给前端变成一串数字后端实体里的LocalDateTime如果不配置序列化格式前端拿到的JSON可能是一串数字比如1681361234567或者是2024-01-08T12:00:00这种带T的格式。在SpringBoot里加一个全局格式配置Configuration public class JacksonConfig { Bean public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { return builder - { builder.simpleDateFormat(yyyy-MM-dd HH:mm:ss); builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss))); builder.deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss))); }; } }这样前后端时间格式统一省去一联调就发现时间对不上的麻烦。6.4 本地文件上传的路径问题本地存储图片时最容易被坑的是路径尤其是Windows和Linux路径分隔符不同。建议配置文件中定义上传根目录代码里用Paths.get(uploadPath).toAbsolutePath().normalize()处理别直接写死D:\\upload这种路径。上传文件时文件名一定要重新生成用UUID或System.currentTimeMillis()加随机数再加原文件扩展名。不要直接使用用户上传的原始文件名否则重名文件会互相覆盖还有路径穿越攻击的风险。访问图片时后端要写一个目录映射Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadPath /); } }6.5 前后端联调时的跨域问题前后端分离以后前端是8080端口后端是8081或9090端口不同端口之间默认有跨域限制。浏览器请求后端会被CORS拦截。解决方案有两个一是在后端写CORS配置类允许指定的前端地址跨域访问二是在前端配置Vite的开发代理。我更推荐第二种生产部署时也可以把前端的静态文件放到nginx再由nginx把/api下的请求反向代理到后端这样整个项目就没有跨域问题。Vite代理配置大概是这样export default defineConfig({ server: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })6.6 分页查询的多个条件同时生效列表接口一般都有分页和筛选。拿商品列表举例可以传入keyword、categoryId、minPrice、maxPrice、sortType。用MyBatis-Plus写分页查询时最容易出现的问题是拼SQL时条件互相覆盖或者全是空条件。规范写法是先把都非空的查询条件拼到LambdaQueryWrapper里校验前先判断字符串是否为空、数值是否为null然后再调用分页查询。分页插件配置时一定要确认PaginationInnerInterceptor已经注册。不注册的话分页查询返回的是全量数据前端翻页永远只有第一页有数据。6.7 商品状态与订单状态的一致性交易流程中商品状态和订单状态必须联动更新这一块前文已经提到。但有一个边界案例要注意商品下单锁定后管理员能不能强制下架如果管理员强制下架了商品买家那笔待支付的订单怎么办我的建议是如果商品存在未完成的订单管理员只能“禁止继续销售”不能直接改商品状态为下架。或者强制下架时把待支付订单一起取消并把商品释放。这个一致性逻辑写清楚代码看起来会非常完整答辩老师很可能追问这一层。7. 项目扩展与评分提升思路7.1 数据统计面板让项目质感上台阶只做增删改查系统看着很“平”。加一个数据统计面板视觉上立刻有质感。用ECharts展示每周新增商品趋势、商品分类占比饼图、订单金额按月统计、捐赠物资数量排行。后端需要提供统计接口比如按月份分组统计订单数SELECT DATE_FORMAT(create_time, %Y-%m) AS month, COUNT(*) AS order_count, SUM(total_amount) AS total_amount FROM orders WHERE status 3 GROUP BY DATE_FORMAT(create_time, %Y-%m) ORDER BY month前端在管理端首页加载这些数据并绘制图表。不要小看这几张图表它在演示环节能直观证明系统每时每刻产生的数据是有价值的。7.2 定时任务扩展SpringBoot里加定时任务非常简单在启动类上加上EnableScheduling然后写一个类用Scheduled(cron 0 0/5 * * * ?)标记方法即可。可以做一个订单超时自动取消功能每5分钟扫描一次把所有待支付超过30分钟的订单取消同时把关联商品状态从2重置回1。这个定时任务既解决业务问题又体现你对系统健壮性的考虑。7.3 Redis缓存提速如果项目里已经集成了Redis可以做两件事一是缓存商品分类列表因为分类大概率长时间不变二是缓存首页热门的商品ID列表每隔10分钟刷新一次。注意缓存更新的策略商品上下架后要把旧缓存清掉或者设置比较短的过期时间。没有Redis也不要紧用内存版ConcurrentHashMap写一个本地抽象缓存也能达到演示效果只是压测时内存会偏高。7.4 写毕业论文时怎么提炼价值到论文阶段很多同学不知道怎么把这个项目写得有厚度。我提供一个结构思路摘要里强调“构建闲置物品循环利用的信息化管理平台形成二手物品交易和公益捐赠双闭环促进资源节约与再利用”。关键词写“SpringBoot闲置物品循环利用二手交易捐赠管理”。正文第一章绪论背景写资源浪费问题和绿色低碳理念不要扯大政策就写校园里毕业生离校前大量物品被丢弃的现实场景第二章需求分析画用例图和功能图第三章总体设计画系统架构图、数据库ER图第四章详细设计与实现分模块贴类图和核心代码第五章测试写功能测试用例表再补充几个接口测试结果。最容易被忽略的是数据库设计说明务必画出ER图并解释表关系。答辩老师看到ER图会很安心因为你至少证明了自己不是只抄代码。写在最后的实操体会这个题目从选题到完成我反复强调了“链路完整”四个字。很多同学做完一个项目代码量很大但仔细一看全是CRUD页面堆叠用户、商品、订单互相之间的状态流转根本没打通。真正让人眼前一亮的项目不在于用了多少新技术而在于业务逻辑是不是严谨。你把商品从发布到交易、再从交易到评价的全链路走通把捐赠从申请到公示的全链路走通这个系统就已经超过绝大多数同选题项目了。另外一个容易被忽略的是项目运行环境的统一。开发环境、演示环境建议保持一致数据库脚本要可以用一套SQL一次性建好配置文件里不要写死本机IP。尤其是数据库连接如果最后要部署到服务器演示密码、端口这些提前确认清楚别到答辩前一天才去改配置。最后想说多花一点时间在边界条件的处理上。比如用户余额不足时下单会不会报错、商品已下架时还能不能加入购物车、捐赠物品被人申请后还能不能取消。这些细节才是区分“能跑”和“好项目”的分水岭。如果你现在正卡在这个项目上按上面7个章节循序渐进推进先做数据库设计再写后端核心流程最后补前端页面和统计图表整个系统的完成度会非常可观。