評(píng)估業(yè)務(wù)管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn))
這次我們來(lái)看一個(gè)很典型的 Java 畢業(yè)設(shè)計(jì)項(xiàng)目基于 SSM 框架的資產(chǎn)評(píng)估業(yè)務(wù)管理系統(tǒng)。這類(lèi)系統(tǒng)在高校畢業(yè)設(shè)計(jì)里出現(xiàn)頻率很高原因是它把 SSM 開(kāi)發(fā)的核心鏈路完整串起來(lái)了Spring 負(fù)責(zé)對(duì)象管理SpringMVC 負(fù)責(zé)請(qǐng)求分發(fā)MyBatis 負(fù)責(zé)數(shù)據(jù)庫(kù)操作前端再配合 JSP、Bootstrap 渲染頁(yè)面。技術(shù)棧很基礎(chǔ)但業(yè)務(wù)模型足夠?qū)懬宄?shù)據(jù)庫(kù)設(shè)計(jì)、權(quán)限控制和多角色操作流程適合用來(lái)做畢設(shè)初版也適合剛學(xué)完 JavaWeb 的同學(xué)拿來(lái)練手。這個(gè)資產(chǎn)評(píng)估業(yè)務(wù)管理系統(tǒng)本質(zhì)上是一個(gè)圍繞“資產(chǎn)信息錄入 - 評(píng)估項(xiàng)目立項(xiàng) - 評(píng)估人員作業(yè) - 評(píng)估報(bào)告生成”的業(yè)務(wù)流轉(zhuǎn)系統(tǒng)。相比普通的增刪改查它的業(yè)務(wù)鏈更長(zhǎng)涉及用戶(hù)、資產(chǎn)、項(xiàng)目、機(jī)構(gòu)、報(bào)告多張表所以比“圖書(shū)管理”“學(xué)生管理”這類(lèi)項(xiàng)目更有內(nèi)容可寫(xiě)也更能體現(xiàn)你對(duì)數(shù)據(jù)庫(kù)設(shè)計(jì)和項(xiàng)目結(jié)構(gòu)的理解。本文會(huì)從項(xiàng)目定位、環(huán)境準(zhǔn)備、架構(gòu)設(shè)計(jì)、數(shù)據(jù)庫(kù)設(shè)計(jì)、核心代碼實(shí)現(xiàn)、部署啟動(dòng)、功能測(cè)試和問(wèn)題排查這幾個(gè)維度完整講一遍最后給出幾個(gè)適合寫(xiě)進(jìn)論文的改進(jìn)方向。如果你正在選畢設(shè)題目或者想找一個(gè) SSM 項(xiàng)目邊讀邊改建議先收藏再跟著下面的步驟把系統(tǒng)結(jié)構(gòu)過(guò)一遍。1. 核心能力速覽項(xiàng)目項(xiàng)說(shuō)明項(xiàng)目類(lèi)型Java Web 畢業(yè)設(shè)計(jì) / SSM 框架整合項(xiàng)目技術(shù)棧Spring SpringMVC MyBatis MySQL Maven Tomcat前端方案JSP Bootstrap / Layui可選 Vue3 前后端分離改造開(kāi)發(fā)工具IntelliJ IDEA、Navicat、Postman核心業(yè)務(wù)資產(chǎn)信息管理、評(píng)估項(xiàng)目管理、評(píng)估機(jī)構(gòu)管理、評(píng)估報(bào)告管理、用戶(hù)權(quán)限管理數(shù)據(jù)庫(kù)MySQL 5.7 / 8.0部署方式Maven 打 war 包部署到 Tomcat 8.5適合人群Java 學(xué)習(xí)者、計(jì)算機(jī)專(zhuān)業(yè)畢設(shè)學(xué)生、SSM 入門(mén)開(kāi)發(fā)者擴(kuò)展方向Spring Boot 改造、Vue 前后端分離、Excel 導(dǎo)入導(dǎo)出、Shiro/JWT 權(quán)限增強(qiáng)從表格能看出來(lái)這個(gè)項(xiàng)目的定位不是一個(gè)商業(yè)級(jí)系統(tǒng)而是一個(gè)“結(jié)構(gòu)完整、能跑通、能講清楚”的教學(xué)型系統(tǒng)。它的優(yōu)點(diǎn)是你不需要太多高深知識(shí)把 SSM 的三層架構(gòu)理解熟就能把整個(gè)項(xiàng)目吃透缺點(diǎn)是你如果只做純?cè)鰟h改查答辯時(shí)容易顯得單薄所以后面要重點(diǎn)把業(yè)務(wù)流轉(zhuǎn)和統(tǒng)計(jì)報(bào)表說(shuō)清楚。2. 適用場(chǎng)景與使用邊界這個(gè)系統(tǒng)適合三個(gè)場(chǎng)景。第一種是畢業(yè)設(shè)計(jì)參考。資產(chǎn)評(píng)估行業(yè)本身有明確的業(yè)務(wù)對(duì)象系統(tǒng)里可以用“評(píng)估項(xiàng)目編號(hào) 委托人 評(píng)估機(jī)構(gòu) 評(píng)估報(bào)告”這幾個(gè)核心字段把業(yè)務(wù)串起來(lái)寫(xiě)論文的時(shí)候“需求分析”“數(shù)據(jù)庫(kù)設(shè)計(jì)”“系統(tǒng)實(shí)現(xiàn)”三章都有實(shí)際內(nèi)容支撐。第二種是 SSM 框架學(xué)習(xí)。如果你想練習(xí) SpringMVC 的注解開(kāi)發(fā)、MyBatis 的動(dòng)態(tài) SQL、攔截器做登錄校驗(yàn)這個(gè)系統(tǒng)提供了比較完整的代碼層次比零散寫(xiě) demo 更有價(jià)值。第三種是課程設(shè)計(jì)改造。把頁(yè)面精簡(jiǎn)一下業(yè)務(wù)字段換成其他行業(yè)比如“設(shè)備管理系統(tǒng)”“房屋評(píng)估系統(tǒng)”改造成本不高。同時(shí)也要說(shuō)清楚邊界這不是一個(gè)生產(chǎn)環(huán)境可以直接用的資產(chǎn)評(píng)估平臺(tái)因?yàn)檎嬲脑u(píng)估業(yè)務(wù)涉及估價(jià)模型、法律法規(guī)、報(bào)告合規(guī)審核這些不是普通畢設(shè)系統(tǒng)能覆蓋的。另外如果你是直接用別人開(kāi)源的畢設(shè)源碼一定要注意學(xué)術(shù)誠(chéng)信論文要寫(xiě)自己對(duì)系統(tǒng)的理解代碼要能在本地跑通并說(shuō)清楚每一層的作用否則答辯時(shí)一問(wèn)就暴露了。建議參考源碼的結(jié)構(gòu)然后自己重新建表、重寫(xiě)核心模塊這樣才能真正掌握。3. 開(kāi)發(fā)環(huán)境準(zhǔn)備在開(kāi)始搭建項(xiàng)目之前先確認(rèn)電腦上的基礎(chǔ)環(huán)境。下面是推薦版本盡量保持一致減少踩坑概率。3.1 基礎(chǔ)軟件清單軟件推薦版本說(shuō)明JDKJDK 1.8SSM 項(xiàng)目最穩(wěn)定避免用 JDK 17 出現(xiàn)兼容問(wèn)題Maven3.6.3統(tǒng)一管理依賴(lài)MySQL5.7 或 8.0建庫(kù)時(shí)注意字符集 utf8mb4TomcatTomcat 8.5對(duì)應(yīng) Servlet 3.1匹配 SpringMVCIDEA2020.3 以上社區(qū)版或旗艦版都可以3.2 環(huán)境變量配置Windows 下安裝完 JDK 和 Maven需要配置環(huán)境變量否則 IDEA 里會(huì)提示找不到 Java 或 Maven。# JDK 環(huán)境變量 JAVA_HOME C:\Program Files\Java\jdk1.8.0_202 Path 追加 %JAVA_HOME%\bin # Maven 環(huán)境變量 MAVEN_HOME D:\apache-maven-3.6.3 Path 追加 %MAVEN_HOME%\bin配置完成后在命令行執(zhí)行java -version和mvn -v能正常輸出版本信息就說(shuō)明環(huán)境沒(méi)問(wèn)題。3.3 數(shù)據(jù)庫(kù)準(zhǔn)備在 MySQL 中創(chuàng)建數(shù)據(jù)庫(kù)字符集選擇utf8mb4排序規(guī)則選擇utf8mb4_general_ci。CREATE DATABASE IF NOT EXISTS asset_assess DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE asset_assess;后續(xù)把所有建表 SQL 放到asset_assess.sql腳本里通過(guò) Navicat 或命令行一次性導(dǎo)入。3.4 IDEA 中的 Maven 設(shè)置打開(kāi) IDEA進(jìn)入File - Settings - Maven把 Maven home directory 指向本機(jī)的 Maven 目錄將settings.xml中的本地倉(cāng)庫(kù)路徑配置好最好再配置阿里的鏡像加快依賴(lài)下載速度。這里給出settings.xml里的鏡像片段mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共倉(cāng)庫(kù)/name urlhttps://maven.aliyun.com/repository/public/url /mirror4. 系統(tǒng)總體設(shè)計(jì)4.1 技術(shù)架構(gòu)分層整個(gè)系統(tǒng)采用經(jīng)典 SSM 三層架構(gòu)再加上 Controller 層和 View 層。調(diào)用順序是JSP 頁(yè)面發(fā)起請(qǐng)求 - SpringMVC Controller 接收 - Service 處理業(yè)務(wù) - MyBatis Mapper 訪問(wèn) MySQL返回結(jié)果再逆向回到頁(yè)面。這種分層最大的好處是職責(zé)分離每一層只做自己的事。Controller 不做數(shù)據(jù)庫(kù)操作Service 里不放頁(yè)面跳轉(zhuǎn)邏輯Mapper 只寫(xiě) SQL這樣后面改需求的時(shí)候改動(dòng)范圍可以控制在一個(gè)模塊內(nèi)。4.2 功能模塊設(shè)計(jì)資產(chǎn)評(píng)估業(yè)務(wù)管理系統(tǒng)按角色來(lái)分通常包含以下模塊模塊功能說(shuō)明登錄與用戶(hù)管理管理員登錄、用戶(hù)增刪改查、密碼 MD5 加密資產(chǎn)信息管理資產(chǎn)基本信息的添加、修改、刪除、分頁(yè)查詢(xún)?cè)u(píng)估項(xiàng)目管理創(chuàng)建評(píng)估項(xiàng)目、指派評(píng)估機(jī)構(gòu)、維護(hù)項(xiàng)目狀態(tài)評(píng)估機(jī)構(gòu)管理機(jī)構(gòu)信息維護(hù)項(xiàng)目分配時(shí)關(guān)聯(lián)機(jī)構(gòu)評(píng)估報(bào)告管理報(bào)告上傳、報(bào)告審核狀態(tài)、報(bào)告下載數(shù)據(jù)統(tǒng)計(jì)按資產(chǎn)類(lèi)別和項(xiàng)目月份統(tǒng)計(jì)數(shù)量用于首頁(yè)圖表展示4.3 數(shù)據(jù)庫(kù)表設(shè)計(jì)這是整個(gè)項(xiàng)目最值得寫(xiě)的部分。我給出一個(gè)合理的表結(jié)構(gòu)設(shè)計(jì)字段可以根據(jù)自己的業(yè)務(wù)繼續(xù)補(bǔ)充。第一張表是用戶(hù)表保存系統(tǒng)登錄用戶(hù)信息CREATE TABLE sys_user ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, real_name VARCHAR(50), role VARCHAR(20) DEFAULT ADMIN, phone VARCHAR(20), status INT DEFAULT 1, create_time DATETIME DEFAULT CURRENT_TIMESTAMP );第二張表是資產(chǎn)信息表保存被評(píng)估資產(chǎn)的詳細(xì)數(shù)據(jù)CREATE TABLE asset_info ( id INT PRIMARY KEY AUTO_INCREMENT, asset_code VARCHAR(50) NOT NULL UNIQUE, asset_name VARCHAR(100) NOT NULL, category VARCHAR(50), spec VARCHAR(100), original_value DECIMAL(16,2), net_value DECIMAL(16,2), purchase_date DATE, location VARCHAR(255), remark TEXT, create_time DATETIME DEFAULT CURRENT_TIMESTAMP );第三張表是評(píng)估項(xiàng)目表串聯(lián)資產(chǎn)、委托方和評(píng)估機(jī)構(gòu)CREATE TABLE assess_project ( id INT PRIMARY KEY AUTO_INCREMENT, project_code VARCHAR(50) NOT NULL UNIQUE, project_name VARCHAR(100) NOT NULL, client_name VARCHAR(100), asset_id INT, org_id INT, project_status VARCHAR(20) DEFAULT PENDING, assess_amount DECIMAL(16,2), start_time DATETIME, end_time DATETIME, create_time DATETIME DEFAULT CURRENT_TIMESTAMP );第四張表是評(píng)估機(jī)構(gòu)表CREATE TABLE appraisal_org ( id INT PRIMARY KEY AUTO_INCREMENT, org_name VARCHAR(100) NOT NULL, org_code VARCHAR(50), legal_person VARCHAR(50), address VARCHAR(255), phone VARCHAR(20), qualification VARCHAR(50) );第五張表是評(píng)估報(bào)告表通過(guò)外鍵關(guān)聯(lián)評(píng)估項(xiàng)目CREATE TABLE assess_report ( id INT PRIMARY KEY AUTO_INCREMENT, project_id INT, report_code VARCHAR(50) NOT NULL, report_name VARCHAR(100), report_url VARCHAR(255), report_status VARCHAR(20) DEFAULT DRAFT, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );數(shù)據(jù)庫(kù)設(shè)計(jì)答辯時(shí)最少要能講清楚三件事每個(gè)表是干什么的、表之間的關(guān)系是什么、為什么這么設(shè)計(jì)。這里assess_project作為核心表通過(guò)asset_id關(guān)聯(lián)資產(chǎn)通過(guò)org_id關(guān)聯(lián)機(jī)構(gòu)assess_report再關(guān)聯(lián)項(xiàng)目業(yè)務(wù)鏈路就完整了。5. 核心代碼實(shí)現(xiàn)下面給出系統(tǒng)核心代碼的編寫(xiě)思路。注意以下代碼是 SSM 項(xiàng)目的通用實(shí)現(xiàn)模板類(lèi)名和字段請(qǐng)按你的實(shí)際表結(jié)構(gòu)調(diào)整。5.1 實(shí)體類(lèi)以AssetInfo為例實(shí)體類(lèi)字段與數(shù)據(jù)庫(kù)表對(duì)應(yīng)。這里不引入 Lombok使用原生 getter/setter避免環(huán)境沒(méi)有裝 Lombok 時(shí)報(bào)錯(cuò)。public class AssetInfo { private Integer id; private String assetCode; private String assetName; private String category; private String spec; private BigDecimal originalValue; private BigDecimal netValue; private Date purchaseDate; private String location; private String remark; public Integer getId() { return id; } public void setId(Integer id) { this.id id; } public String getAssetCode() { return assetCode; } public void setAssetCode(String assetCode) { this.assetCode assetCode; } // 其他字段的 getter/setter 同理 }5.2 Mapper 接口與 XMLAssetInfoMapper接口定義數(shù)據(jù)庫(kù)操作方法public interface AssetInfoMapper { AssetInfo selectById(Integer id); ListAssetInfo selectList(AssetInfoQuery query); int insert(AssetInfo assetInfo); int update(AssetInfo assetInfo); int deleteById(Integer id); long count(AssetInfoQuery query); }對(duì)應(yīng)的 Mapper XML 放在resources/mapper/AssetInfoMapper.xml核心查詢(xún)語(yǔ)句select idselectList resultTypecom.example.entity.AssetInfo SELECT * FROM asset_info where if testassetName ! null and assetName ! AND asset_name LIKE CONCAT(%, #{assetName}, %) /if if testcategory ! null and category ! AND category #{category} /if /where ORDER BY create_time DESC /select這里用了 MyBatis 動(dòng)態(tài) SQL支持根據(jù)資產(chǎn)名稱(chēng)和類(lèi)別條件組合查詢(xún)是答辯時(shí)容易加分的一個(gè)點(diǎn)。5.3 Service 層Service 負(fù)責(zé)業(yè)務(wù)邏輯。以“創(chuàng)建評(píng)估項(xiàng)目”為例需要同時(shí)校驗(yàn)資產(chǎn)是否存在、機(jī)構(gòu)是否存在再插入項(xiàng)目記錄Service public class AssessProjectService { Autowired private AssessProjectMapper projectMapper; Autowired private AssetInfoMapper assetInfoMapper; Transactional public boolean createProject(AssessProject project) { AssetInfo assetInfo assetInfoMapper.selectById(project.getAssetId()); if (assetInfo null) { throw new RuntimeException(關(guān)聯(lián)資產(chǎn)不存在); } project.setProjectCode(PRJ System.currentTimeMillis()); project.setProjectStatus(PENDING); return projectMapper.insert(project) 0; } }Transactional保證創(chuàng)建項(xiàng)目時(shí)如果中間步驟報(bào)錯(cuò)整個(gè)事務(wù)回滾不會(huì)產(chǎn)生臟數(shù)據(jù)。5.4 Controller 層Controller 使用Controller注解配合 SpringMVC 處理頁(yè)面跳轉(zhuǎn)數(shù)據(jù)通過(guò)Model傳遞到 JSPController RequestMapping(/asset) public class AssetInfoController { Autowired private AssetInfoService assetInfoService; RequestMapping(/list) public String list(AssetInfoQuery query, Model model) { PageResult pageResult assetInfoService.queryPage(query); model.addAttribute(pageResult, pageResult); model.addAttribute(query, query); return asset/list; } RequestMapping(/save) public String save(AssetInfo assetInfo) { assetInfoService.saveOrUpdate(assetInfo); return redirect:/asset/list; } RequestMapping(/delete) public String delete(Integer id) { assetInfoService.deleteById(id); return redirect:/asset/list; } }5.5 登錄攔截器系統(tǒng)頁(yè)面不能繞過(guò)登錄直接訪問(wèn)需要實(shí)現(xiàn) SpringMVC 的HandlerInterceptor。public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object user request.getSession().getAttribute(loginUser); if (user null) { response.sendRedirect(request.getContextPath() /login); return false; } return true; } }然后在spring-mvc.xml里注冊(cè)攔截器并排除登錄接口和靜態(tài)資源mvc:interceptors mvc:interceptor mvc:mapping path/**/ mvc:exclude-mapping path/login/ mvc:exclude-mapping path/static/**/ bean classcom.example.interceptor.LoginInterceptor/ /mvc:interceptor /mvc:interceptors5.6 Spring 與 MyBatis 配置applicationContext.xml中配置數(shù)據(jù)源和 MyBatis 的 Mapper 掃描context:property-placeholder locationclasspath:jdbc.properties/ bean iddataSource classcom.alibaba.druid.pool.DruidDataSource property namedriverClassName value${jdbc.driver}/ property nameurl value${jdbc.url}/ property nameusername value${jdbc.username}/ property namepassword value${jdbc.password}/ /bean bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ property namemapperLocations valueclasspath:mapper/*.xml/ /bean bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.example.mapper/ /beanjdbc.properties內(nèi)容jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/asset_assess?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456這里的數(shù)據(jù)庫(kù)密碼需要改成你自己的本機(jī)密碼。6. 項(xiàng)目部署與啟動(dòng)6.1 IDEA 導(dǎo)入項(xiàng)目在 IDEA 中執(zhí)行File - New - Project from Existing Sources選擇項(xiàng)目的pom.xml之后等待 Maven 自動(dòng)下載依賴(lài)。如果下載很慢檢查第 3 節(jié)中的阿里云鏡像是否配置成功。6.2 Maven 打包在 IDEA 右側(cè) Maven 面板執(zhí)行clean然后執(zhí)行package最終會(huì)在target目錄下生成一個(gè) war 包。mvn clean package -DskipTests6.3 Tomcat 部署如果是 IDEA 集成 Tomcat點(diǎn)擊Run - Edit Configurations - - Tomcat Server - Local選擇 Tomcat 目錄然后在Deployment里添加war explodedApplication context 設(shè)置為/asset。啟動(dòng)后訪問(wèn)地址http://localhost:8080/asset/login如果端口被占用可以在config/server.xml中把 8080 改為 8081。啟動(dòng)成功后使用管理員賬號(hào)登錄系統(tǒng)密碼在sys_user表中預(yù)先初始化也可以在登錄頁(yè)面通過(guò)內(nèi)置的初始化數(shù)據(jù)導(dǎo)入。建議在sql里加入一條初始管理員記錄INSERT INTO sys_user(username, password, real_name, role) VALUES (admin, 202cb962ac59075b964b07152d234b70, 系統(tǒng)管理員, ADMIN);這里的密碼字符串是123的 MD5 值。7. 功能測(cè)試與效果驗(yàn)證系統(tǒng)啟動(dòng)后按順序走一遍核心流程驗(yàn)證系統(tǒng)是否可用。7.1 登錄模塊驗(yàn)證輸入錯(cuò)誤的密碼看是否提示“用戶(hù)名或密碼錯(cuò)誤”。輸入正確賬號(hào)登錄成功后是否跳轉(zhuǎn)到首頁(yè)。未登錄直接訪問(wèn)/asset/list觀察攔截器是否生效并跳轉(zhuǎn)到登錄頁(yè)。7.2 資產(chǎn)信息管理驗(yàn)證點(diǎn)擊資產(chǎn)列表確認(rèn)分頁(yè)展示正常。新增一條資產(chǎn)記錄字段包含資產(chǎn)編碼、資產(chǎn)名稱(chēng)、類(lèi)別、原值、凈值保存后列表是否出現(xiàn)新數(shù)據(jù)。修改某條資產(chǎn)的原值看數(shù)據(jù)庫(kù)和頁(yè)面是否同步。刪除一條資產(chǎn)確認(rèn)列表記錄減少。7.3 評(píng)估項(xiàng)目流程驗(yàn)證創(chuàng)建一個(gè)評(píng)估項(xiàng)目選擇資產(chǎn)和評(píng)估機(jī)構(gòu)。將項(xiàng)目狀態(tài)從“待評(píng)估”改為“評(píng)估中”。給項(xiàng)目上傳一份評(píng)估報(bào)告狀態(tài)變?yōu)椤耙淹瓿伞薄_@里建議用一個(gè)測(cè)試表格記錄結(jié)果測(cè)試模塊測(cè)試步驟預(yù)期結(jié)果是否通過(guò)登錄模塊錯(cuò)誤密碼登錄提示錯(cuò)誤待驗(yàn)證登錄模塊正確賬號(hào)登錄跳轉(zhuǎn)首頁(yè)待驗(yàn)證資產(chǎn)管理新增資產(chǎn)列表出現(xiàn)新記錄待驗(yàn)證評(píng)估項(xiàng)目創(chuàng)建項(xiàng)目并派單項(xiàng)目狀態(tài)更新待驗(yàn)證報(bào)告管理上傳報(bào)告報(bào)告可下載待驗(yàn)證7.4 分頁(yè)與條件查詢(xún)驗(yàn)證在列表中按資產(chǎn)名稱(chēng)關(guān)鍵字搜索確認(rèn) SQL 動(dòng)態(tài)條件生效點(diǎn)擊第 2 頁(yè)確認(rèn)分頁(yè)參數(shù)正常傳遞。分頁(yè)功能建議使用 PageHelper 插件用法簡(jiǎn)單dependency groupIdcom.github.pagehelper/groupId artifactIdpagehelper/artifactId version5.2.1/version /dependencyPageHelper.startPage(pageNum, pageSize); ListAssetInfo list assetInfoMapper.selectList(query); PageInfoAssetInfo pageInfo new PageInfo(list);8. 常見(jiàn)問(wèn)題與排查方法問(wèn)題現(xiàn)象可能原因排查方式解決方案Maven 依賴(lài)下載失敗網(wǎng)絡(luò)問(wèn)題或鏡像未配置檢查settings.xml鏡像配置阿里云鏡像并更新倉(cāng)庫(kù)Tomcat 啟動(dòng)報(bào)端口占用8080 被其他進(jìn)程占用netstat -anofindstr 8080數(shù)據(jù)庫(kù)中文亂碼數(shù)據(jù)庫(kù)字符集不是 utf8mb4查看表字符集重新建庫(kù)連接 URL 加characterEncodingutf8登錄后頁(yè)面 404攔截器把靜態(tài)資源攔截了查看日志和請(qǐng)求路徑排除/static/**和/loginLombok 編譯報(bào)錯(cuò)實(shí)體類(lèi)用了Data但未裝插件IDEA 提示找不到 getter/setter安裝 Lombok 插件或者實(shí)體類(lèi)不使用 Lombokjava.lang.OutOfMemoryErrorTomcat 內(nèi)存不足查看catalina.out日志修改 catalina.sh 中的JAVA_OPTS調(diào)大-XmxMyBatis 綁定異常Mapper 接口和 XML 不匹配檢查 namespace 和 id確保接口方法名和 XML id 完全一致訪問(wèn) 500 錯(cuò)誤SQL 字段與實(shí)體類(lèi)不對(duì)應(yīng)看控制臺(tái)完整錯(cuò)誤棧比對(duì)數(shù)據(jù)庫(kù)字段和實(shí)體屬性源發(fā)行版 17 需要目標(biāo)發(fā)行版 17Maven 編譯 JDK 版本過(guò)高檢查項(xiàng)目pom.xml統(tǒng)一為 JDK 1.8設(shè)置maven.compiler.source和target出現(xiàn)問(wèn)題時(shí)最有效的排查順序是先看控制臺(tái)報(bào)錯(cuò)的前三行再確認(rèn)數(shù)據(jù)庫(kù)連接是否正常最后檢查 Mapper XML 的 namespace。很多時(shí)候 500 錯(cuò)誤就是字段名寫(xiě)錯(cuò)或者大小寫(xiě)不匹配。另外啟動(dòng)項(xiàng)目時(shí)如果遇到Annotation processing is not supported for module cycles說(shuō)明 Spring 模塊和實(shí)體類(lèi)模塊存在循環(huán)依賴(lài)需要把公共類(lèi)單獨(dú)抽到一個(gè)模塊里或者調(diào)整包結(jié)構(gòu)對(duì)多數(shù) SSM 單項(xiàng)目來(lái)說(shuō)直接把兩個(gè)類(lèi)放到同一個(gè)模塊即可。9. 最佳實(shí)踐與畢設(shè)改進(jìn)方向如果只是把增刪改查寫(xiě)完這個(gè)系統(tǒng)還不夠有競(jìng)爭(zhēng)力。建議從以下幾個(gè)方向做增強(qiáng)。9.1 增加角色權(quán)限目前sys_user表只有一個(gè)role字段如果希望管理員、評(píng)估人員、普通用戶(hù)看到不同菜單可以引入攔截器判斷角色更復(fù)雜的可以引入 Shiro。答辯時(shí)能講清“不同權(quán)限訪問(wèn)不同資源”會(huì)比單純做登錄校驗(yàn)更有亮點(diǎn)。9.2 增加 Excel 導(dǎo)入導(dǎo)出資產(chǎn)信息往往需要批量導(dǎo)入使用 Apache POI 或者 EasyExcel 實(shí)現(xiàn) Excel 導(dǎo)入導(dǎo)出是業(yè)務(wù)系統(tǒng)里非常常見(jiàn)的需求。比如在資產(chǎn)列表頁(yè)提供“批量導(dǎo)入”按鈕上傳 Excel 后解析并插入數(shù)據(jù)庫(kù)這個(gè)功能寫(xiě)進(jìn)論文也很有價(jià)值。9.3 改造成 Spring Boot 版本目前基于 SSM 的配置比較繁瑣Spring Boot 可以大量簡(jiǎn)化配置。改造時(shí)只需要保留 Controller、Service、Mapper 三層代碼把 XML 配置替換為自動(dòng)配置。熱詞里也出現(xiàn)了vue3 連接 ssm 框架說(shuō)明前后端分離是當(dāng)前主流方向你可以用 Vue3 Element Plus 替換 JSP后端只提供 JSON 接口這樣項(xiàng)目會(huì)更有時(shí)代感。9.4 加入日志與數(shù)據(jù)統(tǒng)計(jì)使用 SLF4J 記錄關(guān)鍵操作日志評(píng)估項(xiàng)目首頁(yè)統(tǒng)計(jì)待評(píng)估、評(píng)估中、已完成的項(xiàng)目數(shù)量用 ECharts 展示柱狀圖或餅圖。這些屬于非功能需求但能顯著提升系統(tǒng)觀感。9.5 代碼規(guī)范與目錄管理模型文件、SQL 腳本、接口文檔分別建目錄業(yè)務(wù)代碼放入controller、service、mapper三個(gè)包前端頁(yè)面按模塊建文件夾。保留一份最小可運(yùn)行配置這份配置只包含 JDK、Maven、MySQL、Tomcat方便在任何機(jī)器上快速恢復(fù)環(huán)境。10. 總結(jié)與下一步基于 SSM 框架的資產(chǎn)評(píng)估業(yè)務(wù)管理系統(tǒng)最值得參考的是它的業(yè)務(wù)流設(shè)計(jì)從資產(chǎn)到項(xiàng)目到報(bào)告一張核心表把多個(gè)業(yè)務(wù)實(shí)體串起來(lái)數(shù)據(jù)庫(kù)設(shè)計(jì)有內(nèi)容可講代碼分層清楚適合作為畢設(shè)初版。拿到這個(gè)項(xiàng)目后第一件事不是急著看完整代碼而是先建庫(kù)、導(dǎo)數(shù)據(jù)、啟動(dòng)項(xiàng)目把登錄、資產(chǎn)新增、項(xiàng)目創(chuàng)建這三條主流程走通。最容易踩的坑集中在環(huán)境上主要是 Maven 依賴(lài)下載慢、Tomcat 端口沖突、MySQL 字符集亂碼。如果你本地已經(jīng)裝過(guò)多個(gè)版本的 JDK還要注意 IDEA 里 Project Structure 和 Maven 的 JDK 設(shè)置必須保持一致否則源發(fā)行版 17 需要目標(biāo)發(fā)行版 17這類(lèi)編譯錯(cuò)誤會(huì)直接把你卡住。后續(xù)可以按照上面的改進(jìn)方向繼續(xù)擴(kuò)展想要系統(tǒng)看起來(lái)更現(xiàn)代就給后端加一個(gè) Spring Boot 版本想要業(yè)務(wù)邏輯更有深度就加上 Excel 導(dǎo)入導(dǎo)出和 ECharts 統(tǒng)計(jì)報(bào)表想要答辯更有亮點(diǎn)就講清楚登錄攔截器、事務(wù)回滾、動(dòng)態(tài) SQL 這幾個(gè)設(shè)計(jì)點(diǎn)。建議收藏備用。真正動(dòng)手的時(shí)候把本文的建庫(kù)腳本、項(xiàng)目結(jié)構(gòu)和核心代碼作為參考自己從頭寫(xiě)一遍遇到問(wèn)題再回來(lái)對(duì)照排查這樣你的項(xiàng)目不只是能跑還能講明白。