基于SSM框架的智慧社区停车管理系统开发实战指南

发布时间:2026/7/1 5:29:32
基于SSM框架的智慧社区停车管理系统开发实战指南 1. 先搞清楚“智慧停车管理子系统”到底要做什么如果你正在做计算机毕设或者想找一个能跑通、能写进简历的Java Web项目“智慧社区停车管理子系统”是个不错的选择。它听起来有“智慧”和“管理”两个关键词但落到代码上核心其实就是对社区内车位、车辆、停车记录和费用进行增删改查CRUD再配上一些业务规则比如临时车计费、月租车管理、车位状态监控。很多人一上来就去看SSM框架怎么整合结果把业务逻辑给忽略了。这个项目的价值在于它能把Java Web开发里最核心的几件事串起来用Spring MVC处理请求用MyBatis操作MySQL数据库再用JSP或Thymeleaf做个管理界面。做完之后你不仅能说“我会SSM”还能具体讲清楚一个业务模块从前端表单到后端逻辑再到数据库落地的完整流程。所以别被“智慧”吓到。我们先拆解它的核心功能模块基础数据管理车位信息编号、位置、类型、车主/车辆信息。停车业务车辆入场记录、出场记录、计算停车时长和费用。收费管理区分临时车按小时计费和月租车固定费用定期生效。状态监控实时查看车位占用情况空闲/占用。统计查询按日、月统计停车收入查询某辆车的停车记录。把这些功能点理清楚你的项目就有了骨架剩下的就是用SSM技术栈去实现它。2. 环境与工具准备别在第一步卡住项目跑不起来一半的问题出在环境上。下面是我建议的配置清单版本不求最新但求稳定兼容。开发环境JDK: 1.8 或 11。建议用1.8兼容性最好。别用太新的避免依赖库不匹配。配置好JAVA_HOME和PATH。IDE: IntelliJ IDEA 或 Eclipse。IDEA对Maven和Spring的支持更友好能省不少事。项目构建: Maven。用它来管理Jar包依赖比手动导入省心太多。技术栈依赖 (在pom.xml中配置)Spring: 4.3.x 或 5.x。包含spring-core, spring-webmvc, spring-context等。Spring MVC: 通常随Spring Web一起引入。MyBatis: 3.4.x 或 3.5.x。MyBatis-Spring整合包:mybatis-spring版本要和MyBatis、Spring匹配。数据库驱动:mysql-connector-java版本5.1.x或8.0.x。连接池: 推荐com.alibaba.druidDruid它自带监控功能方便排查SQL问题。JSP相关:javax.servlet-api,jstl。日志:log4j或slf4jlogback。数据库MySQL: 5.7 或 8.0。建议用5.7更成熟。记得下载安装并启动服务。客户端工具: Navicat、MySQL Workbench或IDEA自带的数据库工具。用于建库、建表、测试SQL。关键一步统一版本号在pom.xml的properties里定义版本号变量这是避免依赖冲突的好习惯。properties spring.version5.2.8.RELEASE/spring.version mybatis.version3.5.6/mybatis.version mybatis.spring.version2.0.6/mybatis.spring.version mysql.version8.0.26/mysql.version druid.version1.2.8/druid.version /properties3. 数据库设计表结构决定代码怎么写数据库设计是项目的基石。设计不好后面写SQL和Java实体类都会很别扭。围绕核心功能我们至少需要这几张表1. 车位表 (parking_space)CREATE TABLE parking_space ( space_id int(11) NOT NULL AUTO_INCREMENT COMMENT 车位ID, space_number varchar(20) NOT NULL COMMENT 车位编号如A001, space_type tinyint(4) NOT NULL COMMENT 车位类型0固定月租1临时, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 状态0空闲1占用, owner_id int(11) DEFAULT NULL COMMENT 关联的车主ID月租车位专用, PRIMARY KEY (space_id), UNIQUE KEY uni_space_number (space_number) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT车位信息表;设计要点space_number必须唯一。owner_id关联月租车主临时车位此项为空。2. 车主/车辆表 (car_owner)CREATE TABLE car_owner ( owner_id int(11) NOT NULL AUTO_INCREMENT COMMENT 车主ID, owner_name varchar(50) NOT NULL COMMENT 车主姓名, phone varchar(20) NOT NULL COMMENT 联系电话, plate_number varchar(15) NOT NULL COMMENT 车牌号, car_type tinyint(4) DEFAULT 0 COMMENT 车辆类型0月租车1临时车, monthly_fee decimal(10,2) DEFAULT NULL COMMENT 月租费用, valid_start_date date DEFAULT NULL COMMENT 月租有效期开始, valid_end_date date DEFAULT NULL COMMENT 月租有效期结束, PRIMARY KEY (owner_id), UNIQUE KEY uni_plate_number (plate_number) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT车主及车辆信息表;设计要点plate_number车牌号唯一。月租车才需要填写费用和有效期字段。3. 停车记录表 (parking_record)CREATE TABLE parking_record ( record_id int(11) NOT NULL AUTO_INCREMENT COMMENT 记录ID, plate_number varchar(15) NOT NULL COMMENT 车牌号, space_number varchar(20) NOT NULL COMMENT 车位编号, entry_time datetime NOT NULL COMMENT 入场时间, exit_time datetime DEFAULT NULL COMMENT 出场时间, parking_duration int(11) DEFAULT NULL COMMENT 停车时长分钟, parking_fee decimal(10,2) DEFAULT NULL COMMENT 停车费用, payment_status tinyint(4) DEFAULT 0 COMMENT 支付状态0未支付1已支付, PRIMARY KEY (record_id), KEY idx_plate_number (plate_number), KEY idx_entry_time (entry_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT停车记录表;设计要点这是核心业务表。exit_time、parking_duration、parking_fee在车辆出场时更新。建立车牌号和入场时间的索引便于查询。4. 收费规则表 (fee_rule可选但推荐)CREATE TABLE fee_rule ( rule_id int(11) NOT NULL AUTO_INCREMENT, rule_name varchar(50) DEFAULT NULL COMMENT 规则名称如临时车日间费率, first_hour_fee decimal(10,2) DEFAULT NULL COMMENT 首小时费用, per_hour_fee decimal(10,2) DEFAULT NULL COMMENT 后续每小时费用, daily_max_fee decimal(10,2) DEFAULT NULL COMMENT 24小时最高费用, is_active tinyint(4) DEFAULT 1 COMMENT 是否生效, PRIMARY KEY (rule_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT收费规则表;设计要点将计费规则配置化而不是硬编码在Java代码里。这样以后调整价格只需改数据库。注意表之间通过plate_number和space_number这样的业务字段关联而不是动辄使用外键约束。在Web应用中这能提供更大的灵活性但需要在应用层保证数据逻辑的一致性。4. SSM框架整合与配置打通任督二脉环境备好数据库建完接下来就是SSM整合。这一步配置文件多容易出错建议按顺序来。1. Maven项目结构与pom.xml创建标准的Maven Web项目结构src/main/java,src/main/resources,src/main/webapp。pom.xml除了定义版本就是把Spring、MyBatis、数据库驱动、连接池、JSP等依赖坐标放进去。记得打包方式设为war。2. Web配置web.xml这是Web应用的入口配置Spring监听器和DispatcherServlet前端控制器。?xml version1.0 encodingUTF-8? web-app ... !-- 1. 配置Spring的监听器加载applicationContext.xml -- context-param param-namecontextConfigLocation/param-name param-valueclasspath:applicationContext.xml/param-value /context-param listener listener-classorg.springframework.web.context.ContextLoaderListener/listener-class /listener !-- 2. 配置Spring MVC的核心控制器DispatcherServlet -- servlet servlet-namespringDispatcherServlet/servlet-name servlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class init-param param-namecontextConfigLocation/param-name param-valueclasspath:spring-mvc.xml/param-value /init-param load-on-startup1/load-on-startup /servlet servlet-mapping servlet-namespringDispatcherServlet/servlet-name url-pattern//url-pattern /servlet-mapping !-- 3. 字符编码过滤器解决中文乱码 -- filter filter-namecharacterEncodingFilter/filter-name filter-classorg.springframework.web.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param init-param param-nameforceEncoding/param-name param-valuetrue/param-value /init-param /filter filter-mapping filter-namecharacterEncodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping /web-app3. Spring核心配置applicationContext.xml这里配置数据源、事务管理、以及扫描Service层和DAO层的Bean。?xml version1.0 encodingUTF-8? beans ... !-- 1. 加载数据库连接属性文件 -- context:property-placeholder locationclasspath:jdbc.properties/ !-- 2. 配置数据源 (使用Druid) -- bean iddataSource classcom.alibaba.druid.pool.DruidDataSource init-methodinit destroy-methodclose property nameurl value${jdbc.url}/ property nameusername value${jdbc.username}/ property namepassword value${jdbc.password}/ property namedriverClassName value${jdbc.driver}/ !-- 连接池其他配置 -- property nameinitialSize value5/ property namemaxActive value20/ /bean !-- 3. 配置SqlSessionFactoryBean将MyBatis和Spring整合 -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ !-- 指定MyBatis全局配置文件位置 -- property nameconfigLocation valueclasspath:mybatis-config.xml/ !-- 指定Mapper XML文件的位置可以使用通配符 -- property namemapperLocations valueclasspath:mapper/*.xml/ !-- 配置实体类别名包 -- property nametypeAliasesPackage valuecom.yourproject.entity/ /bean !-- 4. 配置Mapper扫描器自动创建DAO接口的代理对象 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.yourproject.dao/ property namesqlSessionFactoryBeanName valuesqlSessionFactory/ /bean !-- 5. 开启注解扫描扫描Service层 -- context:component-scan base-packagecom.yourproject.service/ !-- 6. 事务管理器 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean !-- 开启注解驱动的事务管理 -- tx:annotation-driven transaction-managertransactionManager/ /beans对应的jdbc.properties文件jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/smart_parking?useUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.passwordyourpassword4. Spring MVC配置spring-mvc.xml配置控制器扫描、视图解析器、静态资源处理等。?xml version1.0 encodingUTF-8? beans ... !-- 1. 开启注解驱动自动注册RequestMappingHandlerMapping等 -- mvc:annotation-driven/ !-- 2. 扫描Controller层 -- context:component-scan base-packagecom.yourproject.controller use-default-filtersfalse context:include-filter typeannotation expressionorg.springframework.stereotype.Controller/ /context:component-scan !-- 3. 配置视图解析器 (如果用JSP) -- bean classorg.springframework.web.servlet.view.InternalResourceViewResolver property nameprefix value/WEB-INF/views// property namesuffix value.jsp/ /bean !-- 4. 处理静态资源css, js, images -- mvc:default-servlet-handler/ !-- 5. 文件上传解析器如果需要 -- !-- bean idmultipartResolver classorg.springframework.web.multipart.commons.CommonsMultipartResolver property namemaxUploadSize value10485760/ /bean -- /beans5. MyBatis全局配置mybatis-config.xml这里配置一些MyBatis的运行时行为比如开启驼峰命名映射、日志等。?xml version1.0 encodingUTF-8 ? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration settings !-- 开启驼峰命名自动映射 -- setting namemapUnderscoreToCamelCase valuetrue/ !-- 打印查询语句 -- setting namelogImpl valueSTDOUT_LOGGING/ /settings !-- 类型别名可省略因为在SqlSessionFactoryBean中配置了typeAliasesPackage -- !-- typeAliases.../typeAliases -- /configuration配置完成后启动Tomcat如果控制台没有报错并能看到Druid数据源初始化的日志说明SSM框架整合基本成功。5. 从零实现一个核心功能车辆入场我们以“车辆入场”这个最核心的业务为例走一遍从实体类、DAO、Service到Controller的完整开发流程。理解了这一个其他增删改查模块都是类似的。5.1 创建实体类 (Entity)对应parking_record表。package com.yourproject.entity; import java.util.Date; public class ParkingRecord { private Integer recordId; private String plateNumber; private String spaceNumber; private Date entryTime; private Date exitTime; private Integer parkingDuration; // 分钟 private BigDecimal parkingFee; private Integer paymentStatus; // 0未支付1已支付 // 省略getter、setter和toString方法 }5.2 创建DAO接口和Mapper XMLDAO层负责数据库操作。先定义接口再写XML实现SQL。package com.yourproject.dao; import com.yourproject.entity.ParkingRecord; import org.apache.ibatis.annotations.Param; public interface ParkingRecordDao { // 插入一条入场记录 int insertEntryRecord(ParkingRecord record); // 根据车牌号查询未出场的记录用于出场时计算费用 ParkingRecord selectUnExitRecord(Param(plateNumber) String plateNumber); // 更新出场信息时间、时长、费用、状态 int updateExitInfo(ParkingRecord record); // 其他查询方法... }在resources/mapper/目录下创建ParkingRecordDao.xml?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.yourproject.dao.ParkingRecordDao insert idinsertEntryRecord parameterTypeParkingRecord useGeneratedKeystrue keyPropertyrecordId INSERT INTO parking_record (plate_number, space_number, entry_time) VALUES (#{plateNumber}, #{spaceNumber}, #{entryTime}) /insert select idselectUnExitRecord resultTypeParkingRecord SELECT * FROM parking_record WHERE plate_number #{plateNumber} AND exit_time IS NULL LIMIT 1 /select update idupdateExitInfo parameterTypeParkingRecord UPDATE parking_record SET exit_time #{exitTime}, parking_duration #{parkingDuration}, parking_fee #{parkingFee}, payment_status #{paymentStatus} WHERE record_id #{recordId} /update /mapper5.3 创建Service层Service层处理业务逻辑比如入场前检查车位状态、计算费用等。package com.yourproject.service; import com.yourproject.entity.ParkingRecord; import java.util.Date; public interface ParkingRecordService { // 车辆入场 boolean carEntry(String plateNumber, String spaceNumber); // 车辆出场并计算费用 ParkingRecord carExit(String plateNumber); // 计算停车费用临时车逻辑 BigDecimal calculateFee(Date entryTime, Date exitTime); }实现类package com.yourproject.service.impl; import com.yourproject.dao.ParkingRecordDao; import com.yourproject.dao.ParkingSpaceDao; import com.yourproject.entity.ParkingRecord; import com.yourproject.entity.ParkingSpace; import com.yourproject.service.ParkingRecordService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.Date; Service public class ParkingRecordServiceImpl implements ParkingRecordService { Autowired private ParkingRecordDao parkingRecordDao; Autowired private ParkingSpaceDao parkingSpaceDao; Override Transactional // 开启事务保证车位状态和记录插入的一致性 public boolean carEntry(String plateNumber, String spaceNumber) { // 1. 检查车位是否存在且空闲 ParkingSpace space parkingSpaceDao.selectByNumber(spaceNumber); if (space null || space.getStatus() 1) { return false; // 车位不存在或已被占用 } // 2. 创建入场记录 ParkingRecord record new ParkingRecord(); record.setPlateNumber(plateNumber); record.setSpaceNumber(spaceNumber); record.setEntryTime(new Date()); record.setPaymentStatus(0); int insertCount parkingRecordDao.insertEntryRecord(record); // 3. 更新车位状态为“占用” if (insertCount 0) { parkingSpaceDao.updateStatus(spaceNumber, 1); return true; } return false; } Override Transactional public ParkingRecord carExit(String plateNumber) { // 1. 查询未出场的记录 ParkingRecord unExitRecord parkingRecordDao.selectUnExitRecord(plateNumber); if (unExitRecord null) { return null; // 没有入场记录 } // 2. 计算费用这里简化实际需查收费规则表 Date exitTime new Date(); BigDecimal fee calculateFee(unExitRecord.getEntryTime(), exitTime); long duration (exitTime.getTime() - unExitRecord.getEntryTime().getTime()) / (1000 * 60); // 分钟 // 3. 更新记录 unExitRecord.setExitTime(exitTime); unExitRecord.setParkingDuration((int) duration); unExitRecord.setParkingFee(fee); unExitRecord.setPaymentStatus(1); // 假设自动扣费成功 parkingRecordDao.updateExitInfo(unExitRecord); // 4. 释放车位 parkingSpaceDao.updateStatus(unExitRecord.getSpaceNumber(), 0); return unExitRecord; } Override public BigDecimal calculateFee(Date entryTime, Date exitTime) { // 简化计费逻辑首小时5元后续每小时2元24小时最高30元 long minutes (exitTime.getTime() - entryTime.getTime()) / (1000 * 60); if (minutes 60) { return new BigDecimal(5); } long extraHours (minutes - 60 59) / 60; // 向上取整 BigDecimal fee new BigDecimal(5).add(new BigDecimal(extraHours).multiply(new BigDecimal(2))); // 24小时封顶 if (fee.compareTo(new BigDecimal(30)) 0) { fee new BigDecimal(30); } return fee; } }5.4 创建Controller层Controller接收前端请求调用Service并返回结果跳转页面或JSON。package com.yourproject.controller; import com.yourproject.service.ParkingRecordService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; Controller RequestMapping(/parking) public class ParkingRecordController { Autowired private ParkingRecordService parkingRecordService; PostMapping(/entry) ResponseBody // 返回JSON数据 public MapString, Object entry(RequestParam String plateNumber, RequestParam String spaceNumber) { MapString, Object result new HashMap(); boolean success parkingRecordService.carEntry(plateNumber, spaceNumber); result.put(success, success); result.put(message, success ? 入场成功 : 入场失败车位可能已被占用或不存在); return result; } PostMapping(/exit) ResponseBody public MapString, Object exit(RequestParam String plateNumber) { MapString, Object result new HashMap(); ParkingRecord record parkingRecordService.carExit(plateNumber); if (record ! null) { result.put(success, true); result.put(data, record); result.put(message, 出场成功请缴费 record.getParkingFee() 元); } else { result.put(success, false); result.put(message, 出场失败未找到该车辆的入场记录); } return result; } }5.5 前端页面简易JSP示例在/WEB-INF/views/下创建parking.jsp使用jQuery发起Ajax请求。% page contentTypetext/html;charsetUTF-8 languagejava % html head title停车管理/title script srchttps://code.jquery.com/jquery-3.6.0.min.js/script /head body h2车辆入场/h2 车牌号input typetext idplateNumberInbr 车位号input typetext idspaceNumberInbr button onclickcarEntry()入场/button hr h2车辆出场/h2 车牌号input typetext idplateNumberOutbr button onclickcarExit()出场/button div idresult/div script function carEntry() { $.post(${pageContext.request.contextPath}/parking/entry, { plateNumber: $(#plateNumberIn).val(), spaceNumber: $(#spaceNumberIn).val() }, function(data) { $(#result).html(data.message); } ); } function carExit() { $.post(${pageContext.request.contextPath}/parking/exit, { plateNumber: $(#plateNumberOut).val() }, function(data) { if(data.success){ $(#result).html(停车时长 data.data.parkingDuration 分钟 费用 data.data.parkingFee 元); }else{ $(#result).html(data.message); } } ); } /script /body /html至此一个完整的“车辆入场-出场”流程就实现了。你可以通过访问/parking.jsp来测试这个功能。6. 项目扩展与优化让毕设更出彩基础CRUD做完项目能跑通。但如果想让毕设更有亮点可以从以下几个方向扩展6.1 引入Bootstrap或LayUI优化前端用原生的JSP写界面效率低且不好看。引入Bootstrap或LayUI这样的前端框架可以快速搭建出美观的管理后台。把列表展示、表单、弹窗、分页都做起来。6.2 实现更复杂的计费规则把前面提到的fee_rule表用起来。在Service层的calculateFee方法中不再写死规则而是去数据库查询生效的规则来计算。这能体现你的业务抽象能力。6.3 增加数据统计与图表使用ECharts或Highcharts在管理后台增加统计页面。今日收入从parking_record表按exit_time分组统计。车位利用率(占用车位数量 / 总车位数量) * 100%。车辆类型占比统计月租车和临时车的入场次数。 这些图表能让“智慧”和“管理”的味道更浓。6.4 加入登录与权限控制使用Spring Security或Shiro框架实现简单的角色管理如管理员、操作员。不同角色看到的功能菜单不同。这是企业级应用的标配。6.5 编写单元测试为Service层的关键方法如calculateFee编写JUnit单元测试。这能体现你的工程化思维和代码质量意识。6.6 考虑性能与边界情况并发入场多个车辆同时抢一个车位怎么办可以在carEntry方法中对“查询车位状态”和“更新车位状态”这两步操作加数据库行级锁SELECT ... FOR UPDATE或使用乐观锁确保数据一致性。大数据量分页停车记录多了列表查询要支持分页。MyBatis配合PageHelper插件可以轻松实现。操作日志记录关键操作如入场、出场、收费的操作人、时间、IP便于审计。7. 部署上线与常见问题排查本地开发完成最终要部署到服务器上演示或运行。7.1 打包与部署在IDEA中使用Maven的package命令生成项目名.war文件。将war包上传到Tomcat的webapps目录下。启动Tomcat会自动解压war包并部署应用。访问http://服务器IP:端口/项目名/。7.2 常见问题与排查顺序项目跑不起来别慌按这个顺序查404错误页面找不到检查Tomcat是否成功启动控制台有无报错。检查访问的URL路径是否正确特别是项目名Context Path。检查web.xml中DispatcherServlet的url-pattern配置是否为/。检查JSP文件是否放在了WEB-INF/views/目录下如果配置了视图解析器前缀。500错误服务器内部错误看控制台日志这是最重要的。错误信息会直接告诉你哪里出问题。ClassNotFoundException / NoClassDefFoundError依赖的Jar包没找到。检查pom.xml依赖确认是否成功打包到WEB-INF/lib下。BeanCreationExceptionSpring Bean创建失败。检查applicationContext.xml和spring-mvc.xml中的扫描包路径是否正确Bean的依赖注入是否有问题。SQLException数据库连接或SQL错误。检查jdbc.properties中的数据库地址、用户名、密码。检查MySQL服务是否启动。检查SQL语句在Navicat里能否执行。中文乱码确保数据库、表、字段的字符集是utf8mb4。确保JDBC连接URL中有characterEncodingUTF-8。确保web.xml中配置了字符编码过滤器。确保JSP页面开头有% page contentTypetext/html;charsetUTF-8 %。事务不生效检查applicationContext.xml中是否配置了tx:annotation-driven和TransactionManager。检查Service方法是否被Transactional注解并且是在public方法上。检查是否在Controller中直接new了一个Service对象这样事务不会生效必须通过Spring注入。MyBatis映射失败检查applicationContext.xml中SqlSessionFactoryBean的mapperLocations配置路径是否正确。检查Mapper XML文件中的namespace是否和DAO接口的全限定名完全一致。检查实体类字段名和数据库列名是否能正确映射开启驼峰命名或使用resultMap。最后也是最重要的建议不要一次性把整个项目所有功能写完再测试。采用增量开发。先搭好SSM环境连上数据库做一个最简单的“查询所有车位”功能并测试通过。然后再做“新增车位”再做“车辆入场”……每完成一个小功能就测试一遍。这样当出现问题时你很容易定位到是这次新增的代码导致的排查范围小效率高。这个项目做下来SSM的核心流程、数据库设计、业务逻辑分层、前后端交互、问题排查你都经历了一遍完全可以作为你求职时一个扎实的实战项目。