ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

SSM智慧社区管理系统:从数据库建表到核心代码的完整实战

SSM智慧社区管理系统:从数据库建表到核心代码的完整实战 简介基于SSM的智慧社区管理系统毕业设计资源面向计算机相关专业正在准备毕设的学生以及需要项目实战的Java学习者目标是帮助读者掌握Spring、SpringMVC、MyBatis三大框架的整合开发与社区类管理系统的完整实现。整套资源包含源码Zip包、MySQL数据库脚本.sql和项目说明文档.txt共3个文件压缩包总大小约28.3MB内容配套齐全解压后即可导入Eclipse配合Tomcat运行。系统基于B/S架构使用JSP技术开发页面后台框架采用SSM数据库为MySQL主要分为前台和后台两大模块并设置业主、管理员两种角色。功能上覆盖业主信息管理、房产信息管理、社区内容管理、物业收费管理、物业服务管理、服务预约管理、报损报修管理、意见反馈管理、留言交流管理等完整业务链路界面清爽、操作逻辑清晰。项目经过严格调试数据库脚本与源码可直接配合使用适合作为毕业设计、课程设计或SSM框架综合练习的参考原型目前已有6802人学习下载能有效节省从零搭建系统的时间。1. SSM智慧社区管理系统这个毕设课题为什么值得复现一遍每年毕业季都能看到有人在论坛里求“基于SSM的智慧社区管理系统”的源码也有人下了源码却跑不起来最后在答辩前夜对着Tomcat干瞪眼。这个题目看起来不新但它在毕设里属于典型“看着平平无奇、该有的全都有”的类型房屋、业主、缴费、报修、公告、访客几大板块把增删改查、权限拦截、分页搜索、状态流转全串起来了做一遍基本能把SSM框架从请求到数据库的整条链路摸熟。正因为SSM已经被Spring Boot盖过了风头很多教程默认你会自动配置反而把底层细节藏得严严实实。你要在毕设里讲清楚“请求怎么进的Controller、MyBatis怎么帮你在接口和SQL之间传话”SSM这老一套恰恰是最好讲、最多人验证过、也最容易在网上找到对应问题的技术栈。这套系统适合Java后端方向、想稳扎稳打过答辩的人也适合打算在Spring Boot里写业务、但想回头补SSM原理的从业者。接下来我按自己做这类项目时的顺序从数据库设计、工程搭建、核心代码到避坑清单一条条讲。2. 先把数据底座立起来数据库脚本的模块拆分与核心建表 SQL拿到任何基于SSM的智慧社区管理系统源码我第一件事不是看Controller代码而是先把数据库脚本导进本地MySQL跑一遍把表结构理清楚。一个社区管理系统能不能讲出业务深度全看表设计。社区管理本质上是“人和资产”的关系业主是用户房屋是资产缴费和报修是围绕资产发生的事务公告和访客是社区运营的日常动作。常见做法是把数据拆成八个核心模块彼此通过业主ID和房屋ID关联。上次在群里帮人调一个跑不起来的智慧社区项目发现他连建库脚本都没执行还在那儿用Navicat手动一张张建表建到第五张主键都对不上这种进度很难赶上答辩。以我一个人做过的方案为例核心表一般包含房屋表、业主表、缴费表、报修表、公告表、访客表、车位表、管理员表。其中最容易漏细节的是缴费表和报修表恰恰这两张表又最容易被答辩老师追问。设计的时候我会刻意不再建“缴费明细子表”而是把金额和状态直接冗余在缴费表里对毕设体量来说完全够用还省去了一层JOIN的复杂度。我在设计这八张表时会刻意把每种小区里真正会发生的业务状态放进去。比如报修单不止有“待处理”和“已完成”还要有“已关闭”这种状态用来处理业主自己取消报修的情况。访客表要分“预约时间”和“实际到访时间”这样答辩问起“业主不在访客怎么办”时你能答出“超时未确认自动过期”的调度逻辑而不是只能说“查一下”。下面给出最核心的三张表结构其余的表在思维上完全一致配合SQL脚本很容易补全。-- 创建数据库统一使用 utf8mb4避免中文乱码 CREATE DATABASE IF NOT EXISTS smart_community DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE smart_community; -- 房屋表一套房子的唯一标识是“楼栋单元房号” CREATE TABLE house ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 房屋ID, building_no VARCHAR(20) NOT NULL COMMENT 楼栋号, unit_no VARCHAR(20) NOT NULL COMMENT 单元号, room_no VARCHAR(20) NOT NULL COMMENT 房号, area DECIMAL(8,2) DEFAULT NULL COMMENT 建筑面积(平米), house_type VARCHAR(20) DEFAULT NULL COMMENT 户型如三室一厅, property_fee DECIMAL(6,2) DEFAULT NULL COMMENT 每月物业费, owner_id INT DEFAULT NULL COMMENT 当前业主ID空表示未入住, UNIQUE KEY uk_building_unit_room (building_no, unit_no, room_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT房屋表; -- 缴费表把金额、状态、支付方式冗余在一行里 CREATE TABLE payment ( id INT PRIMARY KEY AUTO_INCREMENT, owner_id INT NOT NULL COMMENT 业主ID, house_id INT NOT NULL COMMENT 房屋ID, pay_type VARCHAR(20) NOT NULL COMMENT 费用类型物业费/停车费/水费/电费, amount DECIMAL(10,2) NOT NULL COMMENT 应收金额, pay_status TINYINT NOT NULL DEFAULT 0 COMMENT 0未缴 1已缴, pay_way VARCHAR(20) DEFAULT NULL COMMENT 支付方式现金/微信/支付宝, pay_time DATETIME DEFAULT NULL COMMENT 缴费时间, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 账单生成时间, remark VARCHAR(200) DEFAULT NULL COMMENT 备注, KEY idx_owner_id (owner_id), KEY idx_pay_status (pay_status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT缴费表; -- 报修表状态字段从0到3覆盖报修单的完整生命周期 CREATE TABLE repair ( id INT PRIMARY KEY AUTO_INCREMENT, owner_id INT NOT NULL COMMENT 业主ID, house_id INT NOT NULL COMMENT 房屋ID, title VARCHAR(100) NOT NULL COMMENT 报修标题, content VARCHAR(500) NOT NULL COMMENT 故障描述, repair_type VARCHAR(30) DEFAULT NULL COMMENT 报修类型, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待派单 1处理中 2已完成 3已关闭, worker_name VARCHAR(30) DEFAULT NULL COMMENT 处理人, phone VARCHAR(20) DEFAULT NULL COMMENT 联系电话, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 报修时间, handle_time DATETIME DEFAULT NULL COMMENT 处理完成时间, KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT报修表; -- 插入一条默认管理员密码用的明文只是为了本地演示 INSERT INTO admin_user(username, password, real_name, role) VALUES (admin, admin123, 系统管理员, admin);参数说明里有几个值得记住的细节。房屋表里那个联合唯一键是防重用的否则同一套房被录入两次后面缴费报表统计就会翻车。缴费表的pay_status特意建了索引因为列表页最常用的筛选条件就是这个字段不加索引数据量过万后就有明显卡顿。报修表的状态字段我用了TINYINT而不是字符串一是节省空间二是在Service层判断状态转换时用整数常量更不容易写错。handle_time 很多人会漏掉它记录的是处理完成的那个时间点做报表统计响应时长时它是唯一的时间依据一定要保留。因为外键会导致删除时有各种限制且毕设阶段数据完全由Service层控制这套脚本我一般不放外键约束。管理员账号的密码明文存储也特意加了注释说明目的是方便在本地一键跑通如果你担心答辩被问到安全性提前准备一段“生产环境必须加密存储这里为了演示方便用了明文”的说辞比装作没想过这个问题要加分得多。拿到别人的数据库脚本后你也别直接无脑执行。先看看表里有没有初始化数据没有初始化数据的项目跑起来所有页面都是空的答辩效果很差。我一般的做法是额外补一份data.sql每个模块至少插5条数据包含不同状态、不同楼栋这样列表页的分页和筛选才有东西可展示交叉查询也不会空空如也。数据库脚本这块理顺了后面写Mapper层就像填空。3. 用 Maven 把 SSM 工程搭起来项目结构、依赖清单与三个配置文件SSM 工程跑不起来八成问题都出在依赖冲突或配置文件不一致上。我搭 SSM 项目时习惯用 Maven 管理依赖、打 war 包部署到 Tomcat而不是直接在 IDEA 的 Project Structure 里手动加 jar。手动加 jar 在你自己机器上能跑一换电脑或换到宿舍机器就找不到类太玄学不值得赌。先说项目结构。按 Maven 的标准 webapp 结构来源码和资源分开maven 编译时会自动把 resources 目录下的配置文件拷到 classes 下。只要mapper/*.xml放在src/main/resources/而不是src/main/java/下面MyBatis 扫描时就能在 classpath 里找到它们这一个坑我帮人踩过很多回。然后是依赖版本。SSM 到了今天依赖坐标已经高度固定不用追求最新版本。Spring 5.1.x 配 JDK 8 非常稳定MyBatis 3.5.x 语法成熟mysql-connector-java 用 5.1.47 还是 8.0.x 取决于你的数据库版本。如果你的 MySQL 是 8.0连接驱动要换成com.mysql.cj.jdbc.Driver并且要注意 MySQL 8 默认的认证插件是否兼容。properties spring.version5.1.8.RELEASE/spring.version mybatis.version3.5.3/mybatis.version mysql.version5.1.47/mysql.version /properties dependencies !-- Spring MVC 和 Spring 核心容器 -- dependency groupIdorg.springframework/groupId artifactIdspring-webmvc/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-jdbc/artifactId version${spring.version}/version /dependency !-- MyBatis 与 Spring 集成 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version${mybatis.version}/version /dependency dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version1.3.2/version /dependency !-- 数据库驱动与连接池 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version${mysql.version}/version /dependency dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.1.10/version /dependency !-- JSON 响应与 JSP 标准标签库 -- dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId version2.9.8/version /dependency dependency groupIdjstl/groupId artifactIdjstl/artifactId version1.2/version /dependency dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency /dependencies依赖版本里有三个容易翻车的点。第一个是javax.servlet-api的 scope 必须是provided否则打 war 包时会把 servlet-api 也打进去Tomcat 加载时和它自己的 servlet-api 冲突启动直接报 NoSuchMethodError。第二个是mybatis-spring版本不能太新也不能太老1.3.x 系列和 Spring 5.x 兼容良好换成 2.x 反而要额外确认 Spring 版本。第三个是 MySQL 驱动我的本机是 MySQL 5.7 就用 5.1.47如果你是 MySQL 8.0就去掉这段依赖换成 8.0.x并把 url 里时区参数补上不然半夜跑批会收到时区报错。配置文件是 SSM 项目的重头戏。三个配置文件各管一段web.xml负责把 DispatcherServlet 和 Spring 容器接进 Tomcatspring-mvc.xml管 Controller 层和视图解析applicationContext.xml管数据源、事务和 Service 层。很多人喜欢把 Spring 的注解扫描全塞到一个配置文件里图省事结果事务不生效或者请求路径映射乱套很难排查。我习惯分开就是为了让配置边界和代码分层对齐。!-- applicationContext.xml只管 Service/DAO 和事务 -- context:component-scan base-packagecom.example.community !-- 排除Controller它由 spring-mvc.xml 单独扫描 -- context:exclude-filter typeannotation expressionorg.springframework.stereotype.Controller/ /context:component-scan bean iddataSource classcom.alibaba.druid.pool.DruidDataSource property namedriverClassName valuecom.mysql.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/smart_community?useUnicodetrueamp;characterEncodingutf8/ property nameusername valueroot/ property namepassword valueroot/ property nameinitialSize value5/ property namemaxActive value20/ /bean bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ property nametypeAliasesPackage valuecom.example.community.entity/ property namemapperLocations valueclasspath:mapper/*.xml/ /bean bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.example.community.mapper/ /bean tx:annotation-driven transaction-managertransactionManager/ bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean这段配置需要解释清楚MapperScannerConfigurer的作用。它会把 basePackage 下的接口全部扫描出来动态生成代理对象注入到 Service 层所以你在 Service 里写Autowired private PaymentMapper paymentMapper只靠接口就能拿到实现不用写任何 MapperImpl。mapperLocations 指定的是 Mapper XML 的路径这里写成classpath:mapper/*.xml后你所有 SQL 文件都要放在resources/mapper目录下。typeAliasesPackage是让我在 Mapper XML 里可以简写实体类名的关键配置。没有它resultType 必须写全类名com.example.community.entity.Payment有了它直接写Payment就行SQL 可读性更好也减少误写包名的概率。数据源连接串里特意用了characterEncodingutf8配合数据库建库时的 utf8mb4中文从页面到数据库不会乱码。spring-mvc.xml相对简单些只做三件事扫描Controller、配置视图解析器、放行静态资源。视图解析器的 prefix 和 suffix 分别设置为/WEB-INF/jsp/和.jsp这样 Controller 里返回payment/list时Spring 会自动找到/WEB-INF/jsp/payment/list.jsp。WEB-INF目录下的 JSP 不能被 URL 直接访问这也是一种安全习惯。静态资源放行用mvc:default-servlet-handler/或者单独映射静态资源路径不然 css、js 会被 DispatcherServlet 拦截成 404折腾半天发现只是没配置资源映射。4. 把核心流程落成代码登录会话、缴费分页与报修状态流转配置和表结构都就绪后就该动手写业务代码了。智慧社区管理系统看着功能多拆解下来都是同一种模式Controller 接请求、Service 写业务规则、Mapper 查数据库。我把三个最有代表性的功能讲透剩下的模块照着套路填就好。先说登录。登录是所有系统的高频入口也是分层的典型示范。用户提交用户名密码后Controller 调用 ServiceService 从 Mapper 层查出用户记录再校验密码密码通过后把用户信息放进 session同时用拦截器实现“未登录不能进后台”的规则。SSM 里最常见的写法是直接用HttpSession不引入 Spring Security 之类的重型框架这符合毕设场景也方便你在答辩时讲清楚会话机制。!-- UserMapper.xml -- select idselectByUsername resultTypeAdminUser SELECT id, username, password, real_name, role FROM admin_user WHERE username #{username} LIMIT 1 /select// LoginService.java登录逻辑的核心校验 public AdminUser login(String username, String password) { AdminUser user userMapper.selectByUsername(username); if (user null) { throw new RuntimeException(用户不存在); } if (!password.equals(user.getPassword())) { throw new RuntimeException(密码错误); } return user; } // LoginController.java PostMapping(/login) public String login(String username, String password, HttpSession session) { AdminUser user loginService.login(username, password); session.setAttribute(loginUser, user); return redirect:/index; }登录代码里有几个实用细节。LIMIT 1是为了防止同样用户名被插入多条时selectOne 方法直接报“Expected one result”异常加了这个即使数据脏也只取一条程序更抗造。Service 层用 RuntimeException 抛出业务错误然后由全局异常处理器统一捕获并回显到页面这样 Controller 不需要每个方法都 try-catch代码干净很多。session 里只存当前登录用户的实体对象页面里通过 JSTL 的${sessionScope.loginUser.realName}就能显示登录人姓名。然后是缴费管理这是最能体现 SSM 查询功底的功能因为列表页牵扯到多表关联、条件筛选和分页。业主想看“我这栋楼哪些费用没交”管理员想看“按缴费状态过滤的账单”这些需求本质都是同一句 SQL 加上动态条件。SSM 里实现这个靠的是 MyBatis 的动态 SQL我在写业务时遇到最影响开发体验的坑往往就是配置或作用域问题PageHelper 的拦截器是否生效以及 startPage 的使用位置。先看代码。!-- PaymentMapper.xml -- select idselectByCondition resultTypemap SELECT p.*, o.owner_name, h.building_no, h.unit_no, h.room_no FROM payment p JOIN owner o ON p.owner_id o.id JOIN house h ON p.house_id h.id where if testpayType ! null and payType ! AND p.pay_type #{payType} /if if testpayStatus ! null AND p.pay_status #{payStatus} /if if testhouseNo ! null and houseNo ! AND CONCAT(h.building_no, h.unit_no, h.room_no) LIKE CONCAT(%, #{houseNo}, %) /if /where ORDER BY p.create_time DESC /select// PaymentService.java public PageInfoMapString, Object pageQuery(int pageNum, int pageSize, PaymentQuery query) { PageHelper.startPage(pageNum, pageSize); ListMapString, Object list paymentMapper.selectByCondition(query); return new PageInfo(list); }这段代码的含金量集中在where标签和PageHelper.startPage的搭配上。where标签会自动去掉第一个条件前的 AND所以你不用在if里写WHERE 11这种讨巧的写法SQL 看起来也专业得多。CONCAT函数把楼栋、单元、房号拼成一个字符串做模糊查询这样用户输入“3栋1单元502”时不管中间有没有分隔符都能匹配到是个很小的体验优化。分页的使用有一条铁律PageHelper.startPage()调用后紧跟其后的第一条 Mapper 查询才会被自动拼接LIMIT子句中间不要插入任何其他 Mapper 操作或数据访问调用否则分页会作用在错误的查询上导致列表数据错乱。这个道理听起来简单实际项目里最常见的翻车方式就是在 startPage 后加了一个无关的 query然后看着分页查出来的数据发呆半天。PageInfo封装了总条数、总页数、当前页、是否有下一页等所有分页参数页面直接用 JSTL 遍历pageInfo.list就够了不需要自己写计数 SQL。再说报修的状态流转。智慧社区里报修单不是一次性写入就完事它有一个生命周期业主提交待派单→ 管理员指派维修工处理中→ 维修完成已完成或者业主原因取消已关闭。状态字段在表里是 TINYINT在代码里我用常量类来定义这样 Service 层判断逻辑时不会出现魔法数字满天飞的局面。// RepairStatus.java统一管理报修状态常量 public class RepairStatus { public static final int PENDING 0; // 待派单 public static final int PROCESSING 1; // 处理中 public static final int FINISHED 2; // 已完成 public static final int CLOSED 3; // 已关闭 } public void updateStatus(Integer repairId, int targetStatus, String workerName) { Repair repair repairMapper.selectById(repairId); if (repair null) { throw new RuntimeException(报修单不存在); } // 业务规则已关闭的单子不允许再流转 if (repair.getStatus() RepairStatus.CLOSED) { throw new RuntimeException(已关闭的报修单不能修改状态); } repair.setStatus(targetStatus); repair.setWorkerName(workerName); if (targetStatus RepairStatus.FINISHED) { repair.setHandleTime(new Date()); } repairMapper.updateById(repair); }状态流转的逻辑核心是“状态机校验”。每条状态变更只允许从当前状态流转到固定几个合法状态比如待派单可以变成处理中或已关闭但不能直接跳成已完成。这个业务规则写在 Service 层而不是暴露给前端做判断是因为前端选择框可以被绕过只有后端校验才真正可信。handleTime只在状态变更为已完成时写入这样报表统计里不会出现“处理时间为空但状态已经完成”的矛盾数据。这套模式一旦跑通公告管理、访客管理、车位管理都是同一个套路换皮。你能把这个登录分页状态流转的骨架吃透整个系统开发时间至少缩短一半。5. 跑通以后先别急着交差SSM 毕设最容易踩的五个坑从“代码能看”到“运行不报错”之间通常隔着好几个隐约存在又说不清的问题。这几年在社区里帮人调 SSM 项目见到的很多错误反复出现下面这五个坑基本占了跑不起来场景的八成。第一个坑是启动报Invalid bound statement (not found)意思是 Mapper 接口找到了但对应的 SQL 找不到。现象是一启动就报错点功能也全报这个错。原因几乎就三个Mapper XML 里的 namespace 没写成接口全类名XML 没放在resources/mapper目录下导致没被扫描到或者 XML 文件里的方法 id 和接口方法名不一致。解决方法是先打开编译输出目录target/classes看看 mapper 目录和 XML 文件有没有被打包进去。我见过最离奇的一次是 IDEA 把mvc:default-servlet-handler/配错后直接把 XML 当作静态资源配置逻辑搞混乱了虽然少见但值得留意。第二个坑是中文乱码到处显示问号。这种现象往往不是一处配置导致的而是整个链路编码不统一。页面 JSP 用了 GBKMySQL 表是 utf8mb4连接串里又没加characterEncodingutf8三重不一致每次都出现。我以前排查这种问题时常用一套标准操作页面pageEncodingUTF-8、web.xml 配置CharacterEncodingFilter、连接串加useUnicodetruecharacterEncodingutf8、建库建表用 utf8mb4四处统一后乱码从根上解决。第三个坑是分页点第二页时查询条件全部丢失或者 PageHelper 完全没有分页效果。条件丢失的原因常见于分页按钮只跳了pageNum没有带上搜索框里的关键词和费用类型PageHelper 失效则常见于 startPage 和真正查询之间隔着别的 Mapper 操作分页作用到了无关 SQL 上。解决方法是把查询条件都放进一个表单用 GET 提交同时携带页码和筛选参数PageHelper 调用处保证 startPage 后紧跟目标查询这个方法能减少95%的分页类问题。如果你点下一页时条件丢了还有一个补救做法是把条件和页码拼成 URL 参数比如page/2?payType物业费payStatus0在 JSP 的链接里用 JSTL 拼出来。第四个坑出在数据库脚本本身的导出和导入上。用 Navicat 或 IDEA 自带的数据库工具导出脚本时工具默认会带上DROP TABLE IF EXISTS这在你自己电脑上没感觉换台机器重新部署时就会把已有数据全部清掉再重建。另一个高发问题是导出文件编码是 UTF-8但执行导入时工具没有识别直接按系统默认编码读中文数据全部变乱码。我以前第一次交付毕设给同学时就吃过一次忘了带数据脚本的亏他拿着只含表结构的 SQL 跑起来之后每个页面都空空如也还以为是自己写错代码。现在的做法是导出时单独勾选“包含数据”导入时确认文件字符编码。第五个坑是 Tomcat 启动失败或者部署后 ClassNotFound。先看启动日志如果报端口占用用netstat -ano | findstr 8080找到 PID 再结束进程或者直接改server.xml里的端口如果是 ClassNotFound优先确认依赖 scope 是否正确javax.servlet-api必须是providedDruid 和 MyBatis 必须能打进 war 包的WEB-INF/lib目录。排查 war 包内容有个快速方法用压缩软件打开target目录下生成的 war直接看 lib 目录和 classes 目录是否完整。SSM 项目很多“本地能跑、部署就挂”的问题基本都能在这一步现出原形。提示这类问题的共同特点是在自己机器上怎么跑都对换环境就翻车。处理这类问题要习惯一条原则——不要凭感觉改配置每次只改一个变量重启验证后再改下一个。6. 再往前走一步把 SSM 项目平滑迁移到 Spring Boot 的路径如果你手里这个 SSM 智慧社区系统已经能稳定运行我建议答辩前或者工作后做一件事把它迁到 Spring Boot 上跑通一遍。这不仅能让你在答辩时多一个“为什么不用更主流框架”的回答思路也能帮你彻底理解 Spring Boot 到底替你做了哪些原本需要手写的配置。迁移顺序不要乱。先把依赖换上spring-boot-starter-web和mybatis-spring-boot-starter把原来 pom 里的 Spring 全家桶依赖全部删掉。然后新建application.yml把数据源、druid 或默认连接池、mybatis 的 mapper-locations 和 type-aliases-package 写进去。接着写一个配置类用MapperScan(com.example.community.mapper)替代原来的MapperScannerConfigurer再用EnableTransactionManagement替代tx:annotation-driven。entity、mapper、service、controller 这几层代码可以原样复制只用改极少量注解。很多人问“在一个大的后端工程里怎么新建一个后端模块”其实答案跟这个迁移思路很像。复制一套最小的 controller-service-mapper 骨架改包名配置类里扫描新包路径再验证一次链路就通了。SSM 的 Service 层代码在没有 Spring 注解耦合的情况下搬到 Spring Boot 基本零改动这恰恰说明把业务逻辑写在 Service 层而不是 Controller 层有多重要。迁移过程中你会体会到两件事。第一Spring Boot 的自动配置极大减少接线工作但前提是你知道原来那三份 XML 文件里每段配置对应的功能是什么。第二你可以把以前在 SSM 里想加又不敢加的东西顺手加上全局异常处理器、统一返回结构、参数校验注解用 Spring Boot 操作要比在 XML 里配置简单很多。如果时间富余再给登录模块换成拦截器注册到 WebMvcConfigurer 的方式完成度会更高。我做这类老项目有个习惯拿到手先还原数据库脚本、运行老工程确认可用、再动代码结构这个顺序帮我避开了大半次拆除性的问题。无论你是做毕设还是想补 SSM 原理这套智慧社区管理系统都是一块性价比很高的练手砖希望帮到你。本文还有配套的精品资源点击获取
返回列表