SpringBoot社区居民服务系统毕设项目实战:从数据库到部署完整解析
又到了一年一度的毕业设计选题季每年都有大量同学选择 SpringBoot 方向的管理系统课题。如果你正在找难度适中、功能清晰、容易答辩的 Java 毕设项目基于 SpringBoot 的社区居民服务系统是一个非常值得考虑的选题。这类系统的业务模型贴近真实场景技术栈覆盖面广既不会太复杂到无法完成又能把 SpringBoot、MyBatis、MySQL、Thymeleaf 这些核心知识点全部串起来。本文将完整拆解这个毕设项目的技术实现过程从需求分析、功能设计、数据库表结构到 SpringBoot 项目搭建、核心模块实现、运行部署和答辩常见问题全部整理成一套可以直接照做的实战教程。无论你是准备用它做毕业设计还是想练习 SpringBoot 项目开发能力这篇文章都有参考价值。1. 为什么选择社区居民服务系统作为毕设课题1.1 课题背景与选题价值社区居民服务系统本质上是一个典型的 Web 信息管理系统核心业务包括用户信息管理、公告发布、物业报修、活动报名、意见反馈等模块。相比电商系统、支付系统等复杂业务它的业务边界清晰非常适合作为计算机专业毕业设计课题。选这个课题有几点实际好处需求明确社区管理场景大家都熟悉需求分析容易写。功能覆盖经典的增删改查同时包含登录权限、文件上传、状态流转等常用功能点。技术栈主流使用 SpringBoot MyBatis/MyBatis-Plus MySQL 的组合和当前企业开发技术栈贴合。页面展示效果好前后端都有内容答辩时能演示。1.2 系统的核心价值从一个真实的社区管理场景来看传统的社区通知、报修、活动报名往往依赖线下登记或微信群接龙信息分散、容易遗漏、难以统计。社区居民服务系统把这些业务线上化让居民和社区工作人员在同一个平台中完成信息流转这也是系统开发的核心意义所在。答辩时如果能把这个业务背景讲清楚会是一个很好的加分项。1.3 这个课题适合什么样的学生有一定 Java 基础学完 SpringBoot 之后需要一个完整项目练手。毕业设计要求独立完成 Web 系统需要源码、论文和演示视频。想快速完成一个能跑通的毕设项目同时希望代码结构清晰、能被理解。2. 系统功能拆解与角色设计2.1 用户角色划分社区居民服务系统的用户角色一般分为三类不同角色拥有不同的操作权限角色核心职责典型功能系统管理员维护系统基础数据居民管理、工作人员管理、权限分配社区工作人员处理社区日常事务发布公告、处理报修、审核活动报名居民用户使用社区服务功能查看公告、提交报修、报名活动、提交反馈实际开发时角色权限可以通过简单的拦截器实现登录后将用户信息存入 Session请求访问时判断角色标识。2.2 功能模块清单一个完整的社区居民服务系统建议包含以下模块功能模块子功能说明登录模块账号密码登录、退出登录三种角色共用登录入口居民管理居民信息新增、查询、修改、删除管理员维护居民信息房屋管理楼栋-单元-房号维护与管理居民信息关联公告通知公告发布、列表展示、详情查看工作人员发布居民查看报修管理提交报修、查看进度、处理工单居民提交工作人员处理社区活动活动发布、居民报名、报名审核活动列表和报名记录意见反馈反馈提交、反馈处理居民留言工作人员回复个人中心修改个人信息、修改密码登录后可见2.3 技术选型理由项目采用 SpringBoot 作为基础框架主要原因在于SpringBoot 内置 Tomcat简化了部署流程一个 jar 包就能运行。自动配置机制减少了 XML 配置开发效率高。SpringBoot 生态完善可以轻松整合 MyBatis-Plus、Thymeleaf、Redis 等组件。当前企业招聘中 SpringBoot 是高频要求做这个项目对就业也有帮助。3. 环境准备与项目结构规划3.1 开发环境说明以下是本文示例使用的基础环境实际开发时可以按自己的电脑环境调整环境项推荐版本说明JDKJDK 1.8 或 11SpringBoot 2.x 官方支持Maven3.6 及以上依赖管理工具MySQL5.7 或 8.0数据库IDEAIntelliJ IDEA 2022 以上开发工具SpringBoot2.7.x稳定版本MyBatis-Plus3.5.xORM 框架ThymeleafSpringBoot 内置版本服务端模板引擎注意SpringBoot 3.x 目前也已经广泛使用但 3.x 要求 JDK 17 及以上而且部分依赖坐标与 2.x 有差异。如果你所在的学校指定了 JDK 版本请先确认环境再确定 SpringBoot 版本。3.2 项目目录结构实际开发前先把项目结构规划清楚。一个典型的 SpringBoot 分层结构如下community-service ├── src/main/java/com/example/community │ ├── CommunityApplication.java # 启动类 │ ├── config # 配置类拦截器、跨域等 │ ├── controller # 控制层 │ ├── service # 业务层接口 │ │ └── impl # 业务层实现 │ ├── mapper # MyBatis 数据访问层 │ ├── entity # 实体类 │ ├── dto # 数据传输对象 │ ├── common # 通用工具、统一返回结果 │ └── interceptor # 登录拦截器 ├── src/main/resources │ ├── mapper # MyBatis XML 文件 │ ├── static # 静态资源CSS/JS/图片 │ ├── templates # Thymeleaf 页面模板 │ └── application.yml # 配置文件 └── pom.xml分层开发的好处是职责清晰Controller 负责参数接收和页面跳转Service 负责业务逻辑Mapper 负责数据库操作。答辩时被问到项目结构也能解释得有条理。4. 数据库设计与建表 SQL4.1 数据库设计思路数据库设计是毕设项目的重要得分点。社区居民服务系统的数据模型围绕一个核心概念展开人是社区的主体人和房屋绑定人和业务报修、活动、反馈产生关联。基于这个思路核心表分为基础信息表和业务信息表两类。基础信息表包括居民表、工作人员表、房屋表。 业务信息表包括公告表、报修表、活动表、活动报名表、反馈表。4.2 核心建表 SQL下面给出一个可供直接执行的数据库初始化脚本数据库名使用community_db。CREATE DATABASE IF NOT EXISTS community_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE community_db; -- 居民表 CREATE TABLE resident ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, username varchar(50) NOT NULL COMMENT 登录账号, password varchar(100) NOT NULL COMMENT 登录密码, name varchar(50) NOT NULL COMMENT 真实姓名, phone varchar(20) DEFAULT NULL COMMENT 手机号, house_id int DEFAULT NULL COMMENT 房屋ID, gender tinyint DEFAULT NULL COMMENT 性别 0未知 1男 2女, status tinyint DEFAULT 1 COMMENT 状态 0禁用 1正常, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT居民表; -- 房屋表 CREATE TABLE house ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, building varchar(20) DEFAULT NULL COMMENT 楼栋号, unit varchar(20) DEFAULT NULL COMMENT 单元号, room varchar(20) DEFAULT NULL COMMENT 房号, area decimal(10,2) DEFAULT NULL COMMENT 面积, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT房屋表; -- 工作人员表 CREATE TABLE staff ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, username varchar(50) NOT NULL COMMENT 登录账号, password varchar(100) NOT NULL COMMENT 登录密码, name varchar(50) NOT NULL COMMENT 姓名, role tinyint DEFAULT 1 COMMENT 角色 1管理员 2工作人员, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), UNIQUE KEY uk_username (username) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT工作人员表; -- 公告表 CREATE TABLE notice ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, title varchar(100) NOT NULL COMMENT 标题, content text COMMENT 内容, publisher varchar(50) DEFAULT NULL COMMENT 发布人, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 发布时间, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT公告表; -- 报修表 CREATE TABLE repair ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, resident_id int NOT NULL COMMENT 报修居民ID, content varchar(500) NOT NULL COMMENT 报修内容, status tinyint DEFAULT 0 COMMENT 状态 0待处理 1处理中 2已完成, handler varchar(50) DEFAULT NULL COMMENT 处理人, handle_remark varchar(255) DEFAULT NULL COMMENT 处理备注, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 报修时间, update_time datetime DEFAULT NULL COMMENT 处理时间, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT报修表; -- 活动表 CREATE TABLE activity ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, title varchar(100) NOT NULL COMMENT 活动标题, content text COMMENT 活动内容, start_time datetime DEFAULT NULL COMMENT 活动开始时间, location varchar(100) DEFAULT NULL COMMENT 活动地点, max_num int DEFAULT 50 COMMENT 人数上限, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 发布时间, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT社区活动表; -- 活动报名表 CREATE TABLE activity_signup ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, activity_id int NOT NULL COMMENT 活动ID, resident_id int NOT NULL COMMENT 报名居民ID, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 报名时间, PRIMARY KEY (id), UNIQUE KEY uk_activity_resident (activity_id, resident_id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT活动报名表; -- 意见反馈表 CREATE TABLE feedback ( id int NOT NULL AUTO_INCREMENT COMMENT 主键, resident_id int NOT NULL COMMENT 反馈居民ID, content varchar(500) NOT NULL COMMENT 反馈内容, reply varchar(500) DEFAULT NULL COMMENT 回复内容, status tinyint DEFAULT 0 COMMENT 状态 0未回复 1已回复, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 反馈时间, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT1 DEFAULT CHARSETutf8mb4 COMMENT意见反馈表;4.3 初始化测试数据为了方便后续测试插入一条管理员账号和管理员账号INSERT INTO staff (username, password, name, role) VALUES (admin, 123456, 系统管理员, 1); INSERT INTO resident (username, password, name, phone) VALUES (zhangsan, 123456, 张三, 13800138000);这里的密码先用明文方便演示项目开发完成后必须改成加密存储。生产环境中一般使用 BCrypt 或 MD5 盐值加密避免数据库泄露导致账号被冒用。5. SpringBoot 项目搭建与核心配置5.1 创建 SpringBoot 项目打开 IDEA通过File - New - Project - Spring Initializr创建项目填写包名com.example.community项目名community-service。如果 IDEA 创建 SpringBoot 项目时网络超时可以改用https://start.aliyun.com作为 Initializr 地址或者直接在start.spring.io官网下载压缩包再导入 IDEA。5.2 pom.xml 核心依赖创建完成后修改pom.xml添加 Web、MyBatis-Plus、MySQL、Thymeleaf 和 Lombok 依赖?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.14/version relativePath/ /parent groupIdcom.example/groupId artifactIdcommunity-service/artifactId version1.0.0/version namecommunity-service/name description社区居民服务系统/description properties java.version1.8/java.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-thymeleaf/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build /project这里使用 MyBatis-Plus 的原因是它可以大幅简化单表 CRUD 操作内置了BaseMapper提供的selectById、insert、updateById、deleteById等通用方法不需要每个实体类都手写基础 XML。对于毕设项目来说能节省大量时间。5.3 application.yml 配置在src/main/resources/application.yml中写入数据库连接、MyBatis-Plus 和 Thymeleaf 配置server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/community_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: root thymeleaf: cache: false prefix: classpath:/templates/ suffix: .html mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: auto配置项说明spring.datasourceMySQL 驱动、连接地址、账号密码根据本机环境修改password。thymeleaf.cachefalse开发阶段关闭模板缓存修改页面后刷新即可看到效果不用重启。mybatis-plus.mapper-locations指定 XML 文件所在目录。map-underscore-to-camel-casetrue开启数据库下划线字段到实体类驼峰属性的自动映射。log-impl控制台打印 SQL 日志方便调试。5.4 主启动类package com.example.community; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication MapperScan(com.example.community.mapper) public class CommunityApplication { public static void main(String[] args) { SpringApplication.run(CommunityApplication.class, args); } }启动类上有两个关键注解SpringBootApplicationSpringBoot 的核心启动注解包含自动配置、组件扫描等功能。MapperScan扫描 Mapper 接口所在的包让 MyBatis 能自动为接口生成代理实现省去在每个 Mapper 上写Mapper的重复操作。6. 核心功能代码实现6.1 统一返回结果类开发 Web 项目时最好定义一个统一的返回结果类保证前后端交互的数据格式一致。这里先定义一个简单的通用返回类package com.example.community.common; import lombok.Data; Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }6.2 实体类与 Mapper以居民实体为例创建实体类Resident.javapackage com.example.community.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalDateTime; Data TableName(resident) public class Resident { TableId(type IdType.AUTO) private Integer id; private String username; private String password; private String name; private String phone; private Integer houseId; private Integer gender; private Integer status; private LocalDateTime createTime; }MyBatis-Plus 的TableName注解用来指定实体类对应的数据库表名TableId标记主键字段IdType.AUTO表示数据库自增主键。创建 Mapper 接口ResidentMapper.javapackage com.example.community.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.community.entity.Resident; public interface ResidentMapper extends BaseMapperResident { }由于已经继承了BaseMapper这个 Mapper 自动拥有了单表增删改查能力不需要写任何 SQL。如果需要复杂查询再在接口中定义方法并在resources/mapper目录中编写对应 XML。6.3 Service 业务层业务层负责封装具体业务逻辑。创建ResidentService.java接口和实现类package com.example.community.service; import com.baomidou.mybatisplus.extension.service.IService; import com.example.community.entity.Resident; public interface ResidentService extends IServiceResident { Resident login(String username, String password); }package com.example.community.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.community.entity.Resident; import com.example.community.mapper.ResidentMapper; import com.example.community.service.ResidentService; import org.springframework.stereotype.Service; Service public class ResidentServiceImpl extends ServiceImplResidentMapper, Resident implements ResidentService { Override public Resident login(String username, String password) { return lambdaQuery() .eq(Resident::getUsername, username) .eq(Resident::getPassword, password) .one(); } }这里使用 MyBatis-Plus 提供的ServiceImpl和lambdaQuery()来构建条件查询通过 Lambda 表达式引用实体字段可以避免把数据库列名硬编码在代码中字段改名时更容易维护。6.4 Controller 控制层控制层负责接收前端请求、调用业务层并返回结果。居民登录接口示例package com.example.community.controller; import com.example.community.common.Result; import com.example.community.entity.Resident; import com.example.community.service.ResidentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpSession; RestController RequestMapping(/api/resident) public class ResidentController { Autowired private ResidentService residentService; PostMapping(/login) public ResultResident login(RequestBody Resident loginUser, HttpSession session) { Resident resident residentService.login(loginUser.getUsername(), loginUser.getPassword()); if (resident ! null) { session.setAttribute(resident, resident); return Result.success(resident); } return Result.error(账号或密码错误); } PostMapping(/logout) public ResultVoid logout(HttpSession session) { session.removeAttribute(resident); return Result.success(null); } GetMapping(/profile) public ResultResident profile(HttpSession session) { Resident resident (Resident) session.getAttribute(resident); if (resident null) { return Result.error(未登录); } return Result.success(resident); } }需要说明的是RestController适合接口开发场景如果页面使用 Thymeleaf 模板渲染则页面跳转方法应该使用Controller。在一个项目中两者可以共存。6.5 登录拦截器实现为了保证未登录用户无法访问受保护页面需要编写登录拦截器。这里以居民端为例实现HandlerInterceptor接口package com.example.community.interceptor; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object resident request.getSession().getAttribute(resident); if (resident null) { // 未登录跳转到登录页 response.sendRedirect(/login); return false; } return true; } }然后在配置类中注册拦截器并设置放行路径package com.example.community.config; import com.example.community.interceptor.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; Configuration public class WebConfig implements WebMvcConfigurer { Autowired private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/**) .excludePathPatterns( /login, /api/resident/login, /api/staff/login, /css/**, /js/**, /images/** ); } }拦截器配置是一个很容易在答辩中被问到的问题。放行路径要注意两点一是静态资源CSS、JS、图片必须放行否则页面样式全部失效二是登录接口本身必须放行否则用户永远无法登录。6.6 报修工单模块实现报修模块是系统中最有业务逻辑的功能包含居民提交报修、工作人员处理报修、状态流转三个步骤。先创建报修实体类package com.example.community.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.time.LocalDateTime; Data TableName(repair) public class Repair { TableId(type IdType.AUTO) private Integer id; private Integer residentId; private String content; private Integer status; private String handler; private String handleRemark; private LocalDateTime createTime; private LocalDateTime updateTime; }居民提交报修的 Service 方法public boolean submitRepair(Repair repair, Integer residentId) { repair.setResidentId(residentId); repair.setStatus(0); // 默认待处理 repair.setCreateTime(LocalDateTime.now()); return save(repair); }工作人员处理报修的方法public boolean handleRepair(Integer repairId, String handler, String remark) { Repair repair getById(repairId); if (repair null) { return false; } repair.setStatus(2); // 已完成 repair.setHandler(handler); repair.setHandleRemark(remark); repair.setUpdateTime(LocalDateTime.now()); return updateById(repair); }这里的关键点是报修状态字段的变化提交时status0处理中status1完成status2。页面展示时可以通过状态值渲染不同的标签颜色也可以进一步用前端框架优化展示效果。6.7 Thymeleaf 页面示例社区居民服务系统属于毕设项目页面不需要特别复杂利用 Thymeleaf 做服务端渲染即可满足要求。登录页面templates/login.html核心代码!DOCTYPE html html langzh xmlns:thhttp://www.thymeleaf.org head meta charsetUTF-8 title社区居民服务系统-登录/title link relstylesheet th:href{/css/style.css} /head body div classlogin-container h2社区居民服务系统/h2 form th:action{/login} methodpost div label账号/label input typetext nameusername required /div div label密码/label input typepassword namepassword required /div button typesubmit登录/button /form p th:if${error} th:text${error} stylecolor: red;/p /div /body /html公告列表页面templates/notice/list.html核心代码!DOCTYPE html html langzh xmlns:thhttp://www.thymeleaf.org head meta charsetUTF-8 title社区公告/title /head body h1社区公告/h1 table border1 tr th编号/th th标题/th th发布人/th th发布时间/th th操作/th /tr tr th:eachnotice : ${noticeList} td th:text${notice.id}/td td th:text${notice.title}/td td th:text${notice.publisher}/td td th:text${#temporals.format(notice.createTime, yyyy-MM-dd HH:mm)}/td tda th:href{/notice/detail/{id}(id${notice.id})}查看详情/a/td /tr /table /body /htmlThymeleaf 的循环、条件判断和链接表达式是页面开发中最高频的语法。如果对 Thymeleaf 不熟只需要掌握th:text、th:href、th:each、th:if这四类语法就足够完成毕设页面了。6.8 工作人员端功能实现工作人员端的 Controller 负责发布公告、处理报修、审核活动报名等操作。以公告管理为例Controller 中提供以下接口// 发布公告 PostMapping(/notice/publish) public ResultVoid publish(RequestBody Notice notice, HttpSession session) { Staff staff (Staff) session.getAttribute(staff); if (staff null) { return Result.error(未登录); } notice.setPublisher(staff.getName()); noticeService.save(notice); return Result.success(null); } // 分页查询公告 GetMapping(/notice/list) public ResultPageNotice list(RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size) { PageNotice result noticeService.page(new Page(page, size)); return Result.success(result); }使用 MyBatis-Plus 的分页插件时需要先配置分页拦截器。创建一个MybatisPlusConfig配置类package com.example.community.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }不配置分页插件时Page对象也能执行但可能不会正确拼接LIMIT语句导致查出全表数据。这是 MyBatis-Plus 使用中非常典型的一个坑建议提前配好。7. 运行、验证与项目打包7.1 初始化数据库与运行项目第一步在 MySQL 中执行第 4 节的建表 SQL并插入管理员测试账号。第二步修改application.yml中的数据库账号密码。第三步在 IDEA 中运行CommunityApplication主类。控制台输出类似下面的日志即代表启动成功Tomcat started on port(s): 8080 (http) Started CommunityApplication in 2.3 seconds7.2 功能测试流程启动成功后按以下顺序测试核心流程访问http://localhost:8080/login使用zhangsan / 123456登录居民端。登录成功后进入社区公告页面查看公告列表。提交一条报修工单填写报修内容。退出登录使用admin / 123456登录工作人员端。进入报修管理页面处理刚才提交的工单填写处理备注。回到居民端查看报修状态是否为“已完成”。如果能完整走通这个闭环说明项目核心逻辑没有问题。7.3 项目打包部署SpringBoot 项目通过 Maven 可以打包为可执行 jar 包。在 IDEA 终端中执行mvn clean package -DskipTests打包完成后在target目录下会生成community-service-1.0.0.jar通过以下命令启动java -jar target/community-service-1.0.0.jar这种部署方式也是 SpringBoot 相比传统 SSM 项目的一大优势不需要额外安装 Tomcat服务器上只要安装了 JDK 就能运行。8. 常见问题与排查思路实际开发毕设项目的过程中每个人都会遇到各种各样的报错。下面整理几个最高频的问题和排查思路问题现象常见原因解决思路启动报Failed to configure a DataSource数据库连接配置错误或未配置检查application.yml的 url、username、password 是否和本地 MySQL 一致访问页面样式全部丢失静态资源被拦截器拦截在拦截器放行路径中加入/css/**、/js/**等路径中文乱码数据库连接 URL 未指定编码URL 中追加useUnicodetruecharacterEncodingutf8登录接口返回 404Controller 没有加RequestBody或请求路径不匹配检查前端请求地址与后端PostMapping路径是否完全一致分页查询结果不正确没有配置 MyBatis-Plus 分页插件添加MybatisPlusInterceptor并配置PaginationInnerInterceptor端口被占用8080 端口已被其他程序占用运行 netstat -ano页面修改后不生效Thymeleaf 缓存未关闭配置spring.thymeleaf.cachefalse并重启应用IDEA 创建项目超时默认 Spring Initializr 地址访问慢改用阿里云地址https://start.aliyun.com遇到报错最重要的是先看控制台完整异常堆栈关注第一行以Caused by开头的异常信息那才是问题的根本原因。不要只截最后一行日志去搜索引擎查很容易被误导。9. 项目优化方向与答辩建议9.1 可以继续优化的方向如果时间充裕或者想在答辩时展示更多亮点可以从下面几个方向扩展引入 Spring Security 或 Sa-Token 做认证授权。目前示例中使用拦截器 Session 做登录校验实现简单但权限管理能力有限。换成 Spring Security 后可以支持角色权限注解、密码加密、记住我等安全能力这也是企业中更通用的做法。增加文件上传功能。公告模块可以支持上传附件图片报修模块可以上传现场照片这些都能让系统更贴近真实业务。使用 Redis 缓存热点数据。例如公告列表是访问频繁但变化较少的数据可以放到 Redis 中缓存减少数据库查询压力。如果学校没有安装 Redis 环境Windows 下有对应的免安装版本配置起来也很快。引入图表统计。在管理端增加一个数据统计页面用 ECharts 展示报修数量趋势、活动报名人数等视觉效果会比纯表格好很多。9.2 答辩常见问题准备答辩时老师通常不会只让你演示功能还会追问一些技术细节。以下问题建议提前准备为什么选择 SpringBoot 而不是 SSMSpringBoot 自动配置解决的问题是什么项目中的登录校验是怎么实现的如果未登录访问接口会发生什么数据库表之间是什么关系为什么活动报名表要加唯一约束报修功能中状态是怎么流转的还能不能再扩展一个“用户取消”状态如果系统上线后居民数量变大你觉得哪些表会最先出现性能问题回答这些问题不需要背诵标准答案重点是结合自己项目中的实际代码去解释。例如问登录校验时就可以把拦截器的preHandle方法逻辑讲一遍再说明放行路径的设计原因这样显得真实可信。9.3 最后一点建议社区居民服务系统这个课题的价值在于它麻雀虽小但五脏俱全覆盖了一个毕业设计应有的所有核心要素需求分析、数据库设计、后端接口开发、页面渲染、权限控制、项目部署。建议拿到项目后不要急着跑代码先花半天把表和接口之间的关系梳理清楚然后自己动手把每个 Controller 的方法走一遍这样无论是写论文还是参加答辩心里都会有底。跑通项目只是第一步能讲清楚为什么这样设计和实现才是毕设真正应该训练的能力。如果你正在准备这个课题希望这篇文章能帮你少走一些弯路。