ARTICLE DETAIL

资讯详情

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

基于SSM+MySQL的文物管理系统:从环境搭建到答辩演示全流程解析

基于SSM+MySQL的文物管理系统:从环境搭建到答辩演示全流程解析 简介一套基于SSM框架与MySQL数据库的文物管理系统毕业设计资料包适合计算机专业学生用于课程设计、毕业设计以及项目实战参考。系统采用浏览器/服务器结构使用JSP动态页面技术后台选用MySQL数据库覆盖文物分类、文物信息、文物外借、文物维修、留言板、论坛交流等完整功能模块。压缩包约68.17MB共1331个文件以Java后端代码、JSP页面与HTML/CSS/JavaScript前端资源为主另含SQL数据库脚本、论文文档、MP4演示视频以及大量界面素材可支撑从环境配置、代码阅读到演示答辩的全流程。包内论文部分对研究现状、设计目标、系统需求、总体设计、具体实现和测试进行了详细论述便于理解整个系统的设计思路与实现细节。资料目前已有64人学习内容结构清晰、模块完整适合作为管理系统类课程设计与毕业设计的参考范本和二次开发基础。1. 基于 SSMMysql 的文物管理系统这套交付包里到底装了什么文化遗产管理是 JavaWeb 课设和毕设里的高频选题而这个标题最大的特点是“成套”“基于 SSMMysql 的文物管理系统”把源码、论文、PPT、开发文档、演示视频五个交付物绑在一起覆盖了从代码开发、文档撰写到答辩演示的完整链路。SSM 指的是 Spring、SpringMVC、MyBatis 三件套MySQL 负责存文物档案和出入库流水。它解决的问题很具体很多初学者代码能跑但说不清架构论文写完了却没对应一条完整的演示路径。这套东西适合两类人一是正在选毕设或课设题目想快速跑通再二次定制功能的学生二是想复用一套经典单体后台模板、做内部管理工具的开发者。2. 从解压 ZIP 到数据库就绪工程骨架、建库脚本和环境核对拿到这种压缩包第一步不是急着用 IDEA 打开而是先解压、核对内部结构。行业惯例是包内同时放源码目录、sql 脚本和 doc 文档分别对应“能跑的代码”“能建出业务的库”“能答辩的材料”。如果你解压后入口有点乱记住这条判断标准只要看到 pom.xml 和 src/main/java 的层级这就是标准 Maven 工程下面的步骤直接照着走即可。2.1 解压后的标准 SSM 工程Maven 目录结构怎么核对既然标题后缀明确带“源码”第一件事就是把工程目录过一遍。规范的 SSM 文物系统逻辑分层大致是这样不会每个包都完全同名但骨架基本跑不出这个范围heritage-system/ ├── pom.xml # Maven 工程描述文件版本和依赖都在这里 ├── sql/ │ └── heritage.sql # 建库建表脚本通常会带几条测试数据 ├── src/main/ │ ├── java/com/heritage/ │ │ ├── controller/ # SpringMVC 控制器接收请求 │ │ ├── service/ # 业务接口 │ │ │ └── impl/ # 业务实现类事务边界在这里 │ │ ├── mapper/ # MyBatis Mapper 接口 │ │ └── entity/ # 数据库表对应的实体类 │ ├── resources/ │ │ ├── spring/ # Spring 容器配置包括事务配置 │ │ ├── mybatis/ # MyBatis 全局配置和 Mapper XML │ │ └── jdbc.properties # MySQL 连接四要素 │ └── webapp/ │ └── WEB-INF/ │ ├── views/ # JSP 页面 │ └── web.xml # Web 应用部署描述符 └── README.md # 启动说明先读它核对拆包时有两点优先级最高第一pom.xml 是否在根目录没有它说明不是 Maven 工程就要改用传统 lib 导入方式工作量会大一圈第二sql 目录是否存在这决定了你需不需要从零建表。拿到后我一般会先扫一遍 sql 脚本内容确认有无 CREATE DATABASE 语句避免导入时报“No database selected”的尴尬。这个结构本身就是业务模块划分的说明书。controller 收请求、service 写业务、mapper 只碰数据库。后面要二次开发加功能也逃不出“Controller 调 Service、Service 调 Mapper”这个同构调用链骨架不用动。2.2 建库建表脚本从文物主表到流转记录表数据库是这套系统的主心骨。标题点名 MySQL交付脚本多数基于 MySQL 5.7 或 8.0 编写。一个可行的判断方法若演示视频日志里出现 Loading class com.mysql.jdbc.Driver用的就是 5.x 驱动写法若是 com.mysql.cj.jdbc.Driver则是 8.0。建议保持和视频一致的版本避免后期大量排错。下面按 5.7 的兼容写法给一套最小建库脚本表名按文物系统里最常用的命名习惯定为 relic、sys_user、relic_log-- 建库utf8mb4 必须优先定好生僻字和文物名里的繁体写法才不会乱码 DROP DATABASE IF EXISTS heritage; CREATE DATABASE heritage DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE heritage; -- 文物主表一张表装下文物基本属性 CREATE TABLE relic ( id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键, relic_no VARCHAR(32) NOT NULL COMMENT 文物编号业务唯一键, name VARCHAR(64) NOT NULL COMMENT 文物名称, category VARCHAR(32) DEFAULT NULL COMMENT 类别陶器/书画/青铜器/玉器, status TINYINT NOT NULL DEFAULT 0 COMMENT 0在库 1借出 2维修, location VARCHAR(64) DEFAULT NULL COMMENT 存放位置例如东库A-03, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 登记时间, UNIQUE KEY uk_relic_no (relic_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT文物主表; -- 系统用户表登录和权限的最小实现 CREATE TABLE sys_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) NOT NULL, password VARCHAR(64) NOT NULL COMMENT 建议存 MD5/BCrypt 散列, role TINYINT DEFAULT 0 COMMENT 0管理员 1普通操作员 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT系统用户表; -- 文物流转记录表每一次出入库和借展归还都留下流水 CREATE TABLE relic_log ( id INT PRIMARY KEY AUTO_INCREMENT, relic_id INT NOT NULL COMMENT 对应 relic.id, action TINYINT NOT NULL COMMENT 1入库 2出库 3借出 4归还, from_location VARCHAR(64) DEFAULT NULL, to_location VARCHAR(64) DEFAULT NULL, operator_id INT DEFAULT NULL, remark VARCHAR(255) DEFAULT NULL, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_relic_id (relic_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT文物流转日志;脚本里有几处值得细看。relic_no 建唯一索引是业务上防重复登记的最硬约束比在 Service 里先 SELECT 再判断可靠得多status 用 tinyint 而非 varchar能避免入库时出现“在库”“In Stock”这类不一致的脏数据relic_log 只存 relic_id 外键不冗余大量文物字段需要展示详情时再 JOIN 回主表这是典型的三范式写法。如果你下载的脚本是用 mysqldump 导出的开头会出现大段 DROP TABLE 和 LOCK TABLES这是 dump 工具的默认行为不是脚本写坏了。执行顺序只要记住“先建库、再导表”就行。2.3 最小运行环境JDK / Tomcat / MySQL 版本搭配SSM 是“老而稳”的技术栈对环境不挑但版本错配会把一个简单项目卡死在启动阶段。这里给出一套最稳妥的搭配表照着配能省掉一半排错时间组件推荐版本说明JDK1.88u201 及以上SSM 对 JDK 9 的模块化支持不友好别追新Maven3.6.x和 JDK 8 搭配最顺3.8 偶发中央仓库源问题Tomcat8.5.x兼容性最好9.x 也能用但要注意 Servlet 版本MySQL5.7.44 或 8.0.x5.7 对旧驱动和 utf8mb4 都友好IDEA2021 或更新旗舰版社区版也能跑只是少了部分 Tomcat 集成功能网上大量 mysql 安装教程讲的就是 5.7/8.0 的图形化安装照着装的时候盯住两点端口保持 33068.0 的默认认证插件是 caching_sha2_password如果代码里还是 5.x 老驱动登录直接报认证失败。嫌麻烦就在 MySQL 里把用户认证改回 mysql_native_password两种方案都行只要代码和数据库对齐。启动顺序别乱第一步启动 MySQL 并导入 sql 脚本第二步改 jdbc.properties 里的用户名密码第三步用 mvn clean package 打 war 包第四步把 war 丢进 Tomcat 的 webapps 后启动最后浏览器访问 http://localhost:8080/heritage-system/。按这个顺序走每一步都能从日志里定位问题而不是最后一次性冒出一屏报错无从下手。3. 把 SSM 三件套配置衔接好容器、注解和事务边界环境坑排除之后决定系统能不能稳定运行的是 SSM 三件套的配置衔接。不少从网上下载的源码启动时报一堆 NoSuchBeanDefinitionException 或 404原因不是业务代码错而是 Spring 根容器和 SpringMVC 子容器的扫描边界没划清楚。3.1 Spring 与 SpringMVC 的父子容器扫描边界与配置文件职责这是 SSM 配置里最容易翻车的地方先从机制上讲清。整个 Web 工程会启动两个容器Spring 根容器管 service、mapper 等业务组件SpringMVC 子容器管 controller 等 Web 组件。子容器能看见父容器里的 Bean父容器看不见子容器里的 Bean。这个父子关系决定了扫描配置怎么划边界。记住这条分配规则applicationContext.xml 里只扫描 service 和 mapperspring-mvc.xml 里只扫描 controller。如果把 controller 放进根容器扫描事务 AOP 和 MVC 映射会互相干扰表现为“控制器找到了但访问方法 404”或者“事务不生效”反过来把 service 放进 MVC 容器根容器拿不到 service启动直接抛异常。!-- applicationContext.xmlSpring 根容器配置骨架 -- context:component-scan base-packagecom.heritage !-- 排除 Controller把 Controller 留给 SpringMVC 子容器管理 -- context:exclude-filter typeannotation expressionorg.springframework.stereotype.Controller/ /context:component-scan !-- 开启 MyBatis 的 Mapper 扫描要求接口带 Mapper 注解或 XML 能匹配 -- mybatis:scan base-packagecom.heritage.mapper/ !-- 事务管理器必须挂在同一个 DataSource 上否则事务不生效 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean tx:annotation-driven transaction-managertransactionManager/!-- spring-mvc.xml只处理请求映射和静态资源放行 -- context:component-scan base-packagecom.heritage context:include-filter typeannotation expressionorg.springframework.stereotype.Controller/ context:exclude-filter typeannotation expressionorg.springframework.stereotype.Service/ /context:component-scan !-- 开启注解驱动把参数绑定和 JSON 转换交给框架去办 -- mvc:annotation-driven/ mvc:default-servlet-handler/上面两段配置是这类交付项目的通用骨架。重点理解 exclude-filter 和 include-filter 的配合根容器排除 ControllerMVC 容器包含 Controller 再排除 Service两个容器各管一摊又通过父子关系完成协作。实际调试时如果某个 Service 注入不进去先回来看扫描配置是不是把不该排除的排除掉了。动手改配置前有个习惯建议养成先把 resources 目录下的 XML 清单列出来确认 spring 配置和 mybatis 配置是否分开放。看到有人把 Mapper XML 混在 Spring XML 里时最好先按类别重排否则排查起来很痛苦。至于用 XML 还是全注解这种交付项目通常混用不强求统一只要保证每个 Bean 只被扫描一次。3.2 把 SSM 常用注解串起来Controller / Service / Mapper 的联动规则容器边界划好以后业务代码里的 SSM 常用注解就是各层组件互相识别的凭证。最常用的一套组合固定如下Controller标记类是 SpringMVC 控制器类里的方法通过 RequestMapping 暴露成 URL。Service标记业务类交给 Spring 根容器管理事务注解也打在 Service 实现上。Mapper或 Repository标记数据访问层接口MyBatis 会为它生成动态代理实现。Autowired按类型注入依赖Controller 注入 Service、Service 注入 Mapper 都靠它。GetMapping / PostMapping细分请求方法的映射注解比老式 method 属性写法更简洁。下面是一段最小但完整的调用链可以在文物系统里任何模块复刻// RelicController.java Controller RequestMapping(/relic) public class RelicController { Autowired private RelicService relicService; // 进入新增页面 GetMapping(/add) public String addPage() { return relic/add; } // 接收表单提交SpringMVC 自动把表单字段映射到 Relic 对象 PostMapping(/add) public String add(Relic relic) { relicService.addRelic(relic); return redirect:/relic/list; // 重定向避免刷新时重复提交 } }// RelicServiceImpl.java Service public class RelicServiceImpl implements RelicService { Autowired private RelicMapper relicMapper; Override public void addRelic(Relic relic) { relicMapper.insert(relic); } }// RelicMapper.java Mapper public interface RelicMapper { int insert(Relic relic); }这段链路有三个细节得放在最前面讲。第一GetMapping 和 PostMapping 是 Spring 4.3 才引入的派生注解如果项目里还是 Spring 4.2.x就得统一退回 RequestMapping(method RequestMethod.GET/POST)否则直接编译失败。第二insert 返回 int 表示受影响行数Service 层可以拿返回值判断写库是否成功不必依赖异常。第三Controller 里用 redirect 而不用 forward是为了避开表单重复提交——刷新页面时浏览器不会把上一次 POST 再发一次。和这套注解配套的 Mapper XML 放在 resources/mybatis 目录文件名和接口保持一致。有个硬规矩XML 的 namespace 必须严格等于接口全限定名语句 id 等于方法名否则 MyBatis 启动时抛 BindingException。这个异常在 mybatis 源码里反复出现是新手最常踩的绑定错误后文会专门讲排查。3.3 事务配置用声明式事务顶住文物出入库的数据一致性文物管理系统的核心数据不只是文物主表每次出入库和借展都必须同时写“状态变更”和“流转日志”。如果这两步没被同一个事务包住程序中途崩溃就会出现文物状态显示“已借出”日志表里却没有对应记录。标准解法是声明式事务也就是在 Service 方法上打 Transactional让 Spring AOP 在方法前后自动开启、提交或回滚事务。事务要生效前提是 3.1 节里的 transactionManager Bean 已配置并且事务管理器和数据源用同一个 DataSource。事务不生效时的第一排查点就是这个 Bean 有没有接管当前库连接。第二排查点是 Transactional 必须打在 public 方法上且不能在本类内部调用——比如 addRelic 方法内部用 this.otherMethod() 调另一个带事务注解的方法事务会绕过代理直接失效这类问题肉眼很难发现。Override Transactional(rollbackFor Exception.class) public void borrowRelic(Integer relicId, String toLocation, Integer operatorId) { // 第一步改主表状态为“借出”并更新存放位置 relicMapper.updateStatus(relicId, 1, toLocation); // 第二步插入一条流转记录 RelicLog log new RelicLog(); log.setRelicId(relicId); log.setAction(3); // 3借出 log.setFromLocation(东库A-03); log.setToLocation(toLocation); log.setOperatorId(operatorId); relicLogMapper.insert(log); // 第二步抛异常时第一步的状态变更会一起回滚不会留下半截数据 }rollbackFor Exception.class 这个参数值得专门说明Spring 默认只对 RuntimeException 回滚对检查型异常如 IOException 不会回滚。课设项目里显式声明 rollbackFor 是最省心的写法。隔离级别用默认的即可MySQL InnoDB 默认 REPEATABLE READ 对这套系统已经足够稳妥不需要为了展示“学术含量”去手动改成 READ_COMMITTED反而可能引入讲不清楚的并发行为。关于 mysql 事务处理还有一个常被忽略的怪现象事务明明开着数据却直接写进去了。多半是 jdbc.properties 里被设置了 connectionAutoCommittrue把它去掉连接提交时机统一交还给事务管理器。4. 核心业务落地文物登记、出入库与列表分页查询配置骨架立住后就可以沿着业务线把功能跑通。这套系统的功能一般落在登录、文物登记、列表查询、出借归还这几块。登录每个课设都有且做法雷同这里不展开重点讲能体现“管理”二字的三块登记、流转、查询。4.1 文物登记模块从页面表单到数据库的完整调用链登记文物是整个系统的主入口也是验证配置是否正确的最短路径。实体类 Relic 对应 relic 表核心字段是 relicNo、name、category、status、location。页面用一个 POST 表单提交Controller 方法签名直接写 Relic 接收参数SpringMVC 会按表单字段名自动绑定省去逐行 getParameter 的繁琐代码。public class Relic { private Integer id; private String relicNo; private String name; private String category; private Integer status; private String location; // getter/setter 用 IDEA 的 AltInsert 一键生成不手写 }页面表单提交到 /relic/add 后Mapper XML 的 insert 语句如下mapper namespacecom.heritage.mapper.RelicMapper insert idinsert parameterTypecom.heritage.entity.Relic useGeneratedKeystrue keyPropertyid INSERT INTO relic (relic_no, name, category, status, location) VALUES (#{relicNo}, #{name}, #{category}, #{status}, #{location}) /insert /mapperuseGeneratedKeystrue 配 keyPropertyid 这一行要单独划重点它的作用是在插入成功后把数据库自增主键回填到 Java 对象的 id 字段。后面写借展流水时你需要用新增后的 relic.getId() 去关联 relic_log漏掉这个配置拿到的 id 永远是 null关联记录就写不进去。这是数据访问层最典型的“代码看着对但结果就是错”的位置。登记的编号查重可以放在 Service 里先查一次提升用户体验但真正兜底的还是数据库唯一索引。Service 查重只是软约束唯一索引才是硬保险两者叠加才能保证业务上不出现两条相同文物编号的数据。4.2 借展与归还一个事务方法里同时改状态和写流水出入库是这套系统最像“业务”的功能。以“借展出库”为例流程可以拆成三步更新文物状态为“借出”、更新目的地、新增一条流转日志。这三步必须原子执行正是 3.3 节事务要保护的对象。Override Transactional(rollbackFor Exception.class) public void borrowRelic(Integer relicId, String targetLocation, Integer operatorId) { Relic relic relicMapper.selectById(relicId); if (relic null) { throw new RuntimeException(文物不存在无法借出); } if (relic.getStatus() ! 0) { throw new RuntimeException(文物当前不在库状态为 relic.getStatus()); } // 业务校验通过后先更新文物状态为“借出” relicMapper.updateStatus(relicId, 1, targetLocation); // 再插入一条借出流水from_location 取更新前查出来的旧位置 RelicLog log new RelicLog(); log.setRelicId(relicId); log.setAction(3); log.setFromLocation(relic.getLocation()); log.setToLocation(targetLocation); log.setOperatorId(operatorId); relicLogMapper.insert(log); }这段代码里有三个常被问到的设计点。第一业务校验放在事务方法内部校验失败抛 RuntimeException事务被标记回滚如果校验放 Controller 层事务还没开启虽然结果也是“不成功”但不符合“所有变更都在同一事务边界”的语义。第二relic.getStatus() ! 0 直接拿 Integer 和 int 字面量比较Java 会自动拆箱空值场景要留意 NPE严谨写法是判空后再比较。第三from_location 用的是更新前查出来的旧位置这样每一条流水都能完整还原“从哪来到哪去”。入库操作几乎是借出的反向status 改回 0位置改回库房编号action 记 1写流水。归还同理action 记 4。逻辑完全一致复制模板改参数即可。4.3 列表查询的实用写法MySQL 排序、分页 LIMIT 与动态 SQL列表页是用户接触最多的页面也最能体现“查询做得顺不顺手”。SSM 项目里列表无非是“条件查询 分页”但条件不能靠字符串拼接那既容易 SQL 注入又难维护。正确做法是 MyBatis 动态 SQL在 XML 里用 if 和 where 标签拼条件select idsearchRelic resultTypecom.heritage.entity.Relic SELECT id, relic_no, name, category, status, location, create_time FROM relic where if testname ! null and name ! AND name LIKE CONCAT(%, #{name}, %) /if if testcategory ! null and category ! AND category #{category} /if if teststatus ! null AND status #{status} /if /where ORDER BY create_time DESC, id DESC LIMIT #{offset}, #{limit} /selectORDER BY create_time DESC 是最常用的排序方式新登记或新流转的文物排最前。但这里有个 MySQL 排序的边界场景create_time 是 DATETIME同一秒内插入多条记录时排序不稳定。要绝对稳定就加 id DESC 作为第二排序键在 MySQL 排序里“看着稳定”和“真稳定”就差一个字段。分页的 LIMIT 参数不要写死在 XML 里由 Controller 从查询参数接收。常见做法是引入 PageHelper 插件一行 PageHelper.startPage(pageNum, pageSize) 自动拦截下一条 SQL 做 count 和 limit课设项目里手写 LIMIT #{offset}, #{limit} 也完全够用。手工分页时注意 MyBatis 的多参数规则接口方法的每个参数必须加 Param 注解否则报 “Parameter offset not found”。看到这个错去接口方法签名补上 Param(offset) Integer offset 和 Param(limit) Integer limit 即可。5. 高频踩坑实录SSM MySQL 文物系统最容易翻车的 5 个环节这个项目本身不难但它属于典型的“配置比业务更费神”的工程。下面把最容易让新手卡上好几个小时的坑按“现象 → 原因 → 解决”展开可以直接对照排查。5.1 Maven 依赖版本打架Spring 5 配低版本 mybatis-spring现象IDEA 启动 Tomcat 时控制台报 BeanCreationException堆栈能看到 NoSuchBeanDefinitionException 或 ClassNotFoundError业务代码本身没有语法错误。原因SSM 工程年代久网上流传的 pom.xml 依赖版本很混乱。最典型的是 Spring 5.x 配了 mybatis-spring 1.3.x而 mybatis-spring 1.3.2 是基于 Spring 4 编译的跑在 Spring 5 容器里创建 MapperFactoryBean 时直接失败。Maven 依赖传递还会拉进冲突的 spring-jdbc 版本。解决把 pom.xml 里三个核心依赖收敛到同一版本线。常见稳定组合是 Spring 5.1.x mybatis 3.5.x mybatis-spring 2.0.xMySQL 驱动用 5.1.49对应 5.7 库或 8.0.x对应 8.0 库。改完 pom 后执行 mvn clean package 重新拉依赖别只点 IDEA 刷新按钮就当万事大吉。5.2 MySQL 8.0 时区与认证方式不兼容现象数据库装的是 8.0项目里驱动仍是 com.mysql.jdbc.Driver启动时报 “The server time zone value is unrecognized”或登录时报认证插件 caching_sha2_password cannot be loaded。原因MySQL 8.0 默认认证插件换成了 caching_sha2_password旧驱动不认识时区问题则是 8.0 对连接 URL 里的 serverTimezone 参数有强制要求不像 5.7 可以缺省。解决驱动类改成 com.mysql.cj.jdbc.Driver连接 URL 追加 ?serverTimezoneAsia/ShanghaiuseSSLfalsecharacterEncodingutf8。useSSLfalse 还能顺手消掉 SSL 握手警告mysql ssl 连接错误 多半就是这个参数没设置。如果必须用 5.x 老驱动就进 MySQL 把用户认证改回 mysql_native_password执行 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; 再 FLUSH PRIVILEGES。5.3 表单提交中文乱码现象登记“唐三彩”三个字落库后变成“?¤?à????”或“????”。原因三层字符集不一致。JSP 页面编码、Tomcat 的 URIEncoding、JDBC 连接 characterEncoding、MySQL 表字符集只要有一层是 latin1 或 GBK全链路就断。解决统一按 utf8mb4 拉齐。Tomcat 的 server.xml 给 Connector 加 URIEncodingUTF-8JSP 页面第一行 pageEncodingUTF-8web.xml 配 CharacterEncodingFilter强制 request 和 response 都走 UTF-8JDBC 连接串带 characterEncodingutf8最后确认表是 utf8mb4。我的习惯是一上项目就把这五处编码配置先写好比事后逐层排查快得多。5.4 请求路径对不上导致 404现象点“文物管理”菜单浏览器地址栏路径是对的但页面 404Tomcat 日志显示 No mapping found for HTTP request with URI。原因第一是 RequestMapping 的类级注解和方法级注解拼出来的完整路径和 JSP 里的链接不一致第二是静态资源被前端控制器拦截了没放行表现为 CSS、JS、图片全部 404而 JSP 还能打开。解决先把类上的 RequestMapping(/relic) 和方法的 GetMapping(/list) 拼起来得到 /relic/list 才是完整访问路径再核对前端 form action 和 href 是否缺了或多了一层 context path。如果路径正确仍 404去 spring-mvc.xml 看有没有 mvc:default-servlet-handler没有就补上放行静态资源。5.5 表字段下划线名与 Java 驼峰属性映射不上现象查询出来的 Relic 对象 name 有值createTime 永远是 null或者 insert 时报“字段 create_time 不存在”。原因数据库列名下划线写 create_timeJava 属性是驼峰 createTimeMyBatis 默认不做自动映射需要明确开启驼峰转换开关。解决在 mybatis-config.xml 里加 。如果项目走 Spring Boot 方式则在 application.properties 配 mybatis.configuration.map-underscore-to-camel-casetrue。开启后下划线列自动映射到驼峰属性手写 resultMap 的工作量能砍掉一半。6. 验收演示路径把跑通的系统变成答辩故事线压缩包里附带的论文、PPT、开发文档、演示视频不是凑数文件它是一套四层配套开发文档讲代码怎么写演示视频讲页面按什么顺序点论文把功能转成文字和截图PPT 把论文压成答辩能讲的十五到二十页。系统跑通后值得做的事不是急着改代码而是沿着演示视频的路径把功能完整走一遍核对每个页面状态和视频对得上。建议按这个顺序做一次“验收式巡检”登录 → 新增一件文物 → 列表页确认数据出现 → 按名称和类别各做一次查询 → 借出该文物 → 确认列表状态变成“借出” → 归还 → 确认状态回到“在库” → 退出登录。整个过程不超过五分钟但能覆盖系统九成以上的功能点。巡检时把 Tomcat 日志窗口开着每成功一步就在日志里找对应的 SQL 输出能同步确认后端逻辑真的被调用了而不只是页面效果好看。被追问“系统有什么亮点”时不建议回答“我用了 SSM 框架”那只会减分。把话题引向两个当场能验证的点。一个是事务一致性借出时改状态和写流水要么同时成功要么同时回滚演示时故意把流水表字段改错让插入失败展示主表状态未变效果好过任何架构图。另一个是唯一索引重复录入同一个文物编号会被数据库拒绝这也是一个可复现的现场亮点。我自己的习惯是在验收前把每张表的索引和事务边界在笔记里列一遍然后带着问题去点功能比如“文物编号唯一索引到底挡没挡住重复数据”“借出操作断在写日志那一步时主表状态是否真的没变”。带着问题巡检比漫无目的地乱点更能留下印象这套方法不挑项目换成任何管理系统都能直接用。希望帮到你。本文还有配套的精品资源点击获取
返回列表