共享食堂信息系統(tǒng)畢設資源詳解)
簡介在Java Web開發(fā)中三層架構(gòu)與SSM組合Spring、SpringMVC、MyBatis是構(gòu)建中小型管理信息系統(tǒng)的經(jīng)典方案。SSM通過配置文件將控制層、業(yè)務層與數(shù)據(jù)訪問層解耦各層職責清晰配合JSP實現(xiàn)前端數(shù)據(jù)渲染MySQL存儲業(yè)務數(shù)據(jù)可快速實現(xiàn)包括用戶管理、美食分類、食堂管理、菜品信息和訂單管理在內(nèi)的完整業(yè)務鏈路。這種架構(gòu)不僅適用于社區(qū)共享食堂等場景也常作為畢業(yè)設計選題幫助初學者理解從頁面請求、Controller接收、Service處理到Mapper操作數(shù)據(jù)庫的完整調(diào)用鏈。本文結(jié)合社區(qū)共享食堂系統(tǒng)實例解析SSM核心配置、訂單提交鏈路、數(shù)據(jù)庫表設計以及部署常見問題為Java Web方向的學生提供可落地參考。1. 社區(qū)共享食堂信息系統(tǒng)這個畢設資源解決什么問題做過畢設的都知道最怕的不是代碼寫不出來而是題目選完才發(fā)現(xiàn)做不下去。我那屆選了個社區(qū)食堂管理卡在食堂、菜品分類、訂單三個模塊怎么串起來光表結(jié)構(gòu)就返工兩回。這套基于 SSM JSP 的社區(qū)共享食堂信息系統(tǒng)屬于畢業(yè)設計里最典型的“后臺管理 前臺展示”雙端項目后臺用 SSMSpring SpringMVC MyBatis頁面是 JSP數(shù)據(jù)庫用 MySQLJDK 1.8 就能跑。它把主頁、個人中心、用戶管理、美食分類、食堂管理、菜品信息、訂單管理整套流程都實現(xiàn)了適合正在做 Java Web 方向畢設、又不想從零寫框架的人。資源里自帶源碼、數(shù)據(jù)庫腳本、論文、答辯 PPT 和環(huán)境工具包照著裝完環(huán)境導入工程半天內(nèi)能把項目跑起來剩下的時間用來改功能和準備答辯。2. 拆解 SSM 三層從 OrderController 到 MyBatis Mapper 的調(diào)用鏈路2.1 工程目錄結(jié)構(gòu)與角色劃分拿到源碼以后別急著啟動先花十分鐘看一下目錄。SSM 項目雖然是三層結(jié)構(gòu)但很多畢設源碼的包名、配置方式并不完全一樣我習慣先把每個包的作用標出來再動手免得后面改代碼時到處找類。src/ ├── com.xxx.controller // 控制層接收頁面請求 ├── com.xxx.service // 業(yè)務層處理業(yè)務邏輯 ├── com.xxx.dao // 數(shù)據(jù)訪問層Mapper 接口 ├── com.xxx.pojo // 實體類對應數(shù)據(jù)庫表 ├── com.xxx.util // 工具類分頁、MD5 等可選 ├── config/ // Spring、SpringMVC、MyBatis 配置 │ ├── applicationContext.xml │ ├── spring-mvc.xml │ ├── mybatis-config.xml │ └── db.properties └── resources/mapper // MyBatis 的 XML 映射文件 WebContent/ ├── WEB-INF/ │ ├── web.xml │ └── views/ // JSP 頁面目錄 └── static/ // CSS、JS、圖片這套結(jié)構(gòu)里Spring 管業(yè)務對象SpringMVC 管請求路由MyBatis 管數(shù)據(jù)庫操作三者通過配置文件粘合。實體類對應數(shù)據(jù)庫表Mapper 接口定義方法XML 里寫 SQLService 層調(diào) MapperController 層接收前端參數(shù)再調(diào) Service這就是最常見的 SSM 鏈路。有些版本會把 MyBatis 的 SQL 直接寫成注解放在接口里跑起來效果一樣但答辯時老師問“SQL 和業(yè)務分離”的問題你直接用 XML 方式解釋更順。2.2 三個核心配置Spring、SpringMVC、MyBatis 各自負責什么SSM 初學者最容易搞混的就是這三個配置文件。我見過不少同學把數(shù)據(jù)源配到 spring-mvc.xml 里啟動不報錯但事務不起作用查了半天才發(fā)現(xiàn)配置放錯了位置。Spring 的 applicationContext.xml 管數(shù)據(jù)源、事務和 Service 層spring-mvc.xml 只管 Controller 和視圖解析MyBatis 的配置負責 SqlSessionFactory 和 Mapper 掃描。三個文件職責分清楚后邊排查問題會輕松很多。db.properties 里寫的是數(shù)據(jù)庫連接參數(shù)新拿到的項目第一步就是改這里不然連不上你自己的 MySQL。常見的配置長這樣jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/community_canteen?useUnicodetruecharacterEncodingutf8useSSLfalse jdbc.usernameroot jdbc.password123456每臺機器上的數(shù)據(jù)庫密碼不一樣這里必須改成自己本機的。url 里的characterEncodingutf8一定不能刪否則后邊存中文菜品名會亂碼useSSLfalse在新版 MySQL 連接時能省掉一堆警告不影響功能。community_canteen 是數(shù)據(jù)庫名如果腳本建庫時用的別的名字這里要同步改。Spring 配置文件里的關鍵片段是把 Service 和 Mapper 都交給容器管理!-- 掃描 Service 實現(xiàn)類 -- context:component-scan base-packagecom.xxx.service / !-- 配置 SqlSessionFactory -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource / property namemapperLocations valueclasspath:mapper/*.xml / /bean !-- Mapper 接口掃描 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.xxx.dao / /beanbase-package必須對應你代碼里的實際包路徑mapperLocations指向 Mapper XML 文件所在目錄。如果換了包名沒改這里啟動時會提示找不到 Bean這個報錯在畢設里幾乎是必踩的。把這段配置理解成“告訴 Spring 去哪兒找接口實現(xiàn)和 SQL 映射”后面改包結(jié)構(gòu)就知道要連帶改哪些地方。2.3 訂單提交這個功能走完的完整代碼鏈路每個系統(tǒng)都有一條最核心的業(yè)務鏈路這套食堂系統(tǒng)里我認為是“用戶提交訂單”。從點擊下單按鈕到數(shù)據(jù)落庫中間經(jīng)過 Controller、Service、Mapper 三層把這個鏈路讀通了其他功能基本都是同一套寫法。先看 Controller 層Controller RequestMapping(/order) public class OrderController { Autowired private OrderService orderService; // 前端表單提交菜品ID和數(shù)量 RequestMapping(/submit) public String submit(RequestParam(foodId) Integer foodId, RequestParam(num) Integer num, HttpSession session, Model model) { // 從 session 里取當前登錄用戶 User user (User) session.getAttribute(loginUser); if (user null) { return redirect:/login.jsp; } // 構(gòu)造訂單對象 Order order new Order(); order.setUserId(user.getId()); order.setFoodId(foodId); order.setNum(num); order.setStatus(0); // 0 表示待接單 orderService.save(order); model.addAttribute(msg, 下單成功等待食堂接單); return user/order_success; } }這里有兩個細節(jié)值得注意。RequestParam(foodId)對應 JSP 表單或鏈接里的參數(shù)名前后必須完全一致否則 SpringMVC 會報參數(shù)缺失order.setStatus(0)是訂單狀態(tài)的起點后邊后臺管理頁面靠這個字段判斷顯示哪些訂單。如果項目里訂單表還設計了訂單號字段一般在這個方法里用時間戳或 UUID 生成。接著是 Service 層它做的事很簡單——調(diào)用 Mapper 接口但類的命名和事務注解是答辯老師喜歡問的Service Transactional public class OrderServiceImpl implements OrderService { Autowired private OrderMapper orderMapper; Override public void save(Order order) { orderMapper.insert(order); } }Transactional表示整個方法在一個事務里執(zhí)行一旦中途出錯全部回滾。單條插入看不出事務的價值但比如“下單同時扣庫存”這種多表操作沒有事務就會出現(xiàn)庫存減了訂單沒生成的情況。答辯時能主動說出這層設計印象分會好不少。最后落到 MyBatis 的 XML 映射文件insert idinsert parameterTypecom.xxx.pojo.Order insert into orders(user_id, food_id, num, status, create_time) values(#{userId}, #{foodId}, #{num}, #{status}, now()) /insert#{userId}這類寫法是 MyBatis 的預編譯占位符它會自動給參數(shù)加引號同時防止 SQL 注入。很多畢設代碼里有人用${userId}的形式拼接字符串雖然能跑但安全性差答辯時老師如果看到會追問。這里建議統(tǒng)一保留#{}風格也是告訴讀代碼的人你清楚預編譯和字符串拼接的區(qū)別。讀到這里你應該發(fā)現(xiàn)整套 SSM 的套路就是“頁面?zhèn)鲄?→ Controller 收參 → Service 處理 → Mapper 落庫”。后邊不管改用戶管理、菜品管理還是訂單管理第一件事都是先到這個鏈路里找到對應位置改起來才有方向。2.4 JSP 頁面如何把數(shù)據(jù)渲染出來后臺接收數(shù)據(jù)后要展示到頁面上JSP 用 EL 表達式和 JSTL 標簽庫來遍歷集合。比如菜品列表頁的代碼長這樣c:forEach items${foodList} varf div classfood-card img src${f.pic} alt菜品圖片 / h3${f.name}/h3 span${f.price}/span a href${pageContext.request.contextPath}/order/submit?foodId${f.id}num1 立即下單 /a /div /c:forEach${foodList}是 Controller 里放進 Model 的值${f.name}會自動調(diào)用實體類的 getName() 方法這就是 JSP 里最常用的數(shù)據(jù)渲染方式。${pageContext.request.contextPath}用來動態(tài)獲取項目根路徑避免部署時項目名改了導致鏈接 404。這套食堂系統(tǒng)的前端頁面都是這種模式Controller 給數(shù)據(jù)、JSP 循環(huán)輸出、表單提交到指定 URL。3. 數(shù)據(jù)庫設計與字段取舍食堂、菜品、訂單三張核心表的落地3.1 表關系與關鍵字段設計這套系統(tǒng)的后臺功能有用戶管理、美食分類管理、食堂管理、菜品信息管理、訂單管理對應的數(shù)據(jù)庫至少有五張表用戶表、分類表、食堂表、菜品表、訂單表。表之間的關系不算復雜但“菜品掛在哪個分類下、訂單是不是直接存菜品快照”這兩個問題很多畢設設計時沒想清楚導致后邊改需求時數(shù)據(jù)對不上。我整理一下這套項目里最常見的設計方式表名關鍵字段作用userid, username, password, real_name, phone前臺用戶信息categoryid, name, sort菜品的分類如川菜、面食canteenid, name, location, description社區(qū)食堂信息foodid, name, canteen_id, category_id, price, pic, status菜品關聯(lián)食堂和分類ordersid, user_id, food_id, num, status, create_time用戶下單記錄注意 food 表里同時有canteen_id和category_id這意味著菜品既屬于某個食堂也屬于某個分類。頁面上的篩選功能靠的就是這兩個外鍵字段比如“只看第二食堂的川菜”SQL 里就是兩個條件的組合查詢。如果設計時漏了其中一個外鍵篩選功能就得在 Java 代碼里循環(huán)判斷性能和數(shù)據(jù)一致性都很差。3.2 菜品列表的聯(lián)表查詢 SQL 寫法菜品列表往往需要同時顯示食堂名稱和分類名稱而這兩個信息都存在別的表里。常見做法是 MyBatis 的 XML 里寫一個多表關聯(lián)查詢返回一個包含冗余字段的 VO 對象代碼里直接用不用反復查數(shù)據(jù)庫。這種寫法在畢設里非常流行答辯時被問“為什么不用視圖”也能答得上——VO 查詢更靈活不用在數(shù)據(jù)庫里建額外的視圖。select idselectFoodList resultTypecom.xxx.vo.FoodVO select f.id, f.name, f.price, f.pic, f.status, c.name as canteenName, cat.name as categoryName from food f left join canteen c on f.canteen_id c.id left join category cat on f.category_id cat.id where if testcanteenId ! null and f.canteen_id #{canteenId} /if if testcategoryId ! null and f.category_id #{categoryId} /if if testkeyword ! null and keyword ! and f.name like concat(%, #{keyword}, %) /if /where order by f.id desc /selectwhere和if是 MyBatis 動態(tài) SQL 的典型寫法作用是有篩選條件就拼條件沒有條件就查全部。三個參數(shù)分別對應前端頁面可能傳過來的食堂 ID、分類 ID 和搜索關鍵字。left join保證即使菜品沒掛分類也能查出來不會因為關聯(lián)不到數(shù)據(jù)而丟失這條菜品記錄。FoodVO 是查詢結(jié)果專用的實體類它不是任何一張表的完整映射而是“菜品表 食堂名 分類名”的組合。做聯(lián)表查詢時我建議新建 VO 類而不是硬往實體類里加字段原因很簡單food 表本身沒有 canteenName 字段往實體類里塞這種無關字段會讓代碼和前端的對應關系變得混亂。3.3 訂單表要不要冗余菜品信息畢設里的常見取舍訂單業(yè)務里有一個經(jīng)典設計問題訂單表是只存food_id還是把菜品名稱、價格也復制一份存進訂單表。很多同學覺得“存 food_id 就夠了吧要查的時候關聯(lián)一下菜品表就行”這個想法在菜品的價格和名稱都不變的情況下是成立的但真實場景里食堂改價、下架菜品都是常態(tài)。比如用戶 3 月份點了一份西紅柿炒蛋當時價格是 8 塊5 月份食堂調(diào)價到 10 塊。如果訂單表只存 food_id再去關聯(lián)菜品表查價格查出來的就是 10 塊訂單歷史金額對不上。所以常見的畢設做法是訂單表冗余一份food_name和price快照字段下單那一刻把菜品的當時的名稱和價格復制過來之后菜品怎么改都不影響已有訂單。這套系統(tǒng)的 orders 表我建議至少保留這些字段CREATE TABLE orders ( id INT AUTO_INCREMENT PRIMARY KEY, order_no VARCHAR(32) COMMENT 訂單號, user_id INT COMMENT 下單用戶ID, food_id INT COMMENT 菜品ID, food_name VARCHAR(50) COMMENT 菜品名稱快照, price DECIMAL(8,2) COMMENT 下單時價格快照, num INT COMMENT 數(shù)量, status TINYINT DEFAULT 0 COMMENT 0待接單 1已接單 2已完成 3已取消, create_time DATETIME COMMENT 下單時間 );food_name和price就是冗余字段好處是查詢訂單列表時不用并發(fā)關聯(lián)菜品表壞處是如果菜品改名老訂單上顯示的是下單時的名稱這也是符合直覺的——你買的時候它就叫這個名字。答辯時把這個取舍邏輯說清楚老師基本不會再追問。3.4 數(shù)據(jù)庫腳本導入后的自我檢查拿到資源里的 SQL 腳本后先用 Navicat 或命令行執(zhí)行再花兩分鐘檢查數(shù)據(jù)是否完整。檢查清單如下看 user 表有沒有初始管理員賬號看 category 和 canteen 表有沒有示例數(shù)據(jù)看 orders 表是不是空的防止演示時沒有數(shù)據(jù)可看。如果執(zhí)行時報錯九成是字符集和版本問題。SQL 腳本開頭一般有CREATE DATABASE語句建議手動建庫時選擇 utf8mb4再執(zhí)行后續(xù)建表和插入語句。utf8mb4 能存表情符號和生僻字比 utf8 更省心。有些低版本 MySQL 執(zhí)行時遇到ENGINEInnoDB DEFAULT CHARSETutf8mb4報錯說明你的 MySQL 服務器版本太老建議直接換成 5.7 或 8.0 版本再試。4. 部署與聯(lián)調(diào)Eclipse JDK8 MySQL 把項目跑起來4.1 環(huán)境版本怎么搭配才不出問題JSP 項目對環(huán)境的敏感程度比想象中高。JDK 8 配 Tomcat 8.5 是這套 SSM 體系最穩(wěn)的組合互不拖后腿。JDK 11 以上跑老版本 JSP 項目會遇到類庫兼容問題報錯信息里常帶ClassNotFoundException: javax.servlet.jsp之類的內(nèi)容不是代碼寫錯了是版本不匹配。MySQL 選 5.7 或 8.0 都可以但要注意 8.0 的驅(qū)動類名和連接串寫法跟 5.7 不同。如果 db.properties 里的 driver 還是com.mysql.jdbc.Driver而你的 MySQL 是 8.0需要改成com.mysql.cj.jdbc.Driver同時連接串加serverTimezoneAsia/Shanghai不然會報時區(qū)錯誤。Eclipse 建議用 2020 之后帶 Web 插件的版本MyEclipse 和 STS 也都能跑區(qū)別只在于 Tomcat 集成界面的位置。IDEA 導入老式 WebContent 結(jié)構(gòu)的工程會多幾步但配置原理一樣最終都是把項目發(fā)布到 Tomcat 的 webapps 目錄下。4.2 一步步把項目跑起來的完整流程我一般按下面的順序操作每次換新環(huán)境都能在三十分鐘內(nèi)跑通步驟不打亂安裝 JDK 8配置JAVA_HOME環(huán)境變量命令行執(zhí)行java -version確認版本無誤安裝 MySQL執(zhí)行 SQL 腳本導入數(shù)據(jù)庫確認所有表生成成功解壓 Tomcat 8.5記住解壓路徑不要放在帶空格的目錄下打開 Eclipse配置 JDK 8 作為默認 JRE導入源碼工程等構(gòu)建完成后修改 db.properties 里的數(shù)據(jù)庫賬號密碼在 Eclipse 的 Servers 視圖里添加 Tomcat把工程部署到 Tomcat啟動 Tomcat瀏覽器訪問http://localhost:8080/項目名/第七步的“項目名”取決于部署時的上下文路徑英文環(huán)境下默認是工程名。如果工程名是canteen_ssm訪問地址就是http://localhost:8080/canteen_ssm/??刂婆_如果打印出 Spring 容器啟動成功信息并且沒有異常堆棧說明后端已經(jīng)起來了。Eclipse 導入工程的方式有兩種。一種是File → Import → Existing Projects into Workspace適合工程目錄里已經(jīng)帶了.project和.classpath文件的情況另一種是Import → Dynamic Web Project適合只有源碼和配置文件、需要自己生成 Web 工程信息的情況。老畢設資源的工程大多數(shù)是前者直接選中根目錄導入即可。4.3 Tomcat 環(huán)境配置與啟動失敗時先看哪里Tomcat 和 Eclipse 集成后雙擊 Servers 視圖里的 Tomcat 實例能看到端口配置和部署模塊列表。默認 HTTP 端口是 8080如果本機端口被占用改成 8081 或 8090 都行但后邊訪問的 URL 也要跟著改瀏覽器輸入http://localhost:8081/項目名/。改完端口一定要重啟 Tomcat不然不生效。啟動失敗時不要急著翻代碼先看控制臺最底部的異常原因。常見的像“Address already in use”說明端口被占“invalid end of file”屬于配置文件格式問題要檢查 web.xml 或 spring 配置文件的大括號有沒有配對。如果控制臺直接顯示類似Error creating bean with name orderController那就是 Controller 依賴的 Service 沒有注入成功第一反應是去查 applicationContext.xml 的掃描包路徑和 Mapper XML 的 namespace。一個更省事的辦法啟動日志里找到Initializing Spring root WebApplicationContext和SpringMVC initialize這兩行如果在它后面沒有Server startup in的提示說明 Spring 容器初始化完成但 Tomcat 部署還有問題。定位思路就是“逐層確認——先確認 Spring 起來了再確認 SpringMVC 起來了最后確認 JSP 頁面能訪問”。4.4 從注冊到下單的聯(lián)調(diào)驗證方法項目跑起來以后光看到首頁不算成功要走完一整條業(yè)務鏈路才能確認核心功能都正常。我每次部署完都會按“注冊用戶 → 登錄 → 查看菜品列表 → 提交訂單 → 后臺管理修改訂單狀態(tài)”的順序過一遍全流程。具體操作是先點首頁的注冊入口創(chuàng)建一個測試賬號用這個賬號登錄系統(tǒng)。進到主頁后隨機選一個食堂看看該食堂的菜品列表能不能正常加載。點擊下單填數(shù)量提交頁面提示“下單成功”。然后用管理員賬號登錄后臺管理界面進入訂單管理能看到剛才的訂單記錄把狀態(tài)從“待接單”改成“已接單”。任何一個環(huán)節(jié)出現(xiàn) 404 或者數(shù)據(jù)不顯示直接按 URL 找對應的 Controller 方法確認請求參數(shù)名和 JSP 里寫的 name 屬性一致。這個驗證流程走通系統(tǒng)的主干功能就沒問題了。后邊改頁面、換樣式都是細枝末節(jié)不會影響整體運行。5. 避坑排查五條典型的畢設級故障與處置記錄5.1 頁面 404項目明明啟動了現(xiàn)象Tomcat 啟動日志正常首頁能訪問但點進某個功能頁面直接 404。原因大多數(shù)情況是 JSP 放在 WEB-INF 目錄下通過 SpringMVC 視圖解析器返回而 URL 路徑寫錯了。WEB-INF 下的頁面不能直接通過地址欄訪問必須由 Controller 轉(zhuǎn)發(fā)這是很多人不理解的地方。另一種情況是RequestMapping的類級路徑和方法級路徑拼接起來不對多寫或少寫一層。解決先在瀏覽器地址欄直接訪問 Controller 的 URL如果返回 Java 代碼里的邏輯視圖名而非 404說明視圖解析器配置有問題檢查 spring-mvc.xml 里前綴后綴是否正確。如果直接訪問 URL 就 404檢查請求路徑是否和注解值一致。我習慣給每個功能先寫一個最簡單的 Controller 方法返回一個只含一行文字的 JSP把鏈路跑通再往里加頁面內(nèi)容。5.2 中文亂碼登錄用戶名和菜品名全是問號現(xiàn)象前臺注冊的中文用戶名顯示正常但后臺管理列表里變成問號或者反過來管理員在后臺添加的中文菜品名前臺看不到。原因數(shù)據(jù)庫連接串缺少characterEncodingutf8或 JSP 頁面沒有設置pageEncodingutf-8也有可能是 MySQL 表的字符集是 latin1。三處必須同時統(tǒng)一編碼只改一處沒用。解決先執(zhí)行SHOW CREATE TABLE user;看表字符集是否 utf8再檢查 db.properties 連接串最后打開 JSP 文件確認第一行有pageEncodingutf-8且方法里用了 POST 請求。改完以后重啟 Tomcat重新插入一條中文數(shù)據(jù)測試而不是看舊數(shù)據(jù)——舊數(shù)據(jù)的亂碼已經(jīng)存進數(shù)據(jù)庫了需要手動清理才能恢復。5.3 圖片上傳后頁面裂開現(xiàn)象管理員上傳菜品圖片上傳成功前端列表頁圖片位置顯示一個裂開的圖標。原因上傳的圖片被保存到了 Tomcat 部署目錄下的某個文件夾但項目重新部署時這個目錄被清空或者 JSP 里的 img src 路徑寫的是相對路徑跟實際保存位置對不上。老項目的常見做法是把圖片傳到項目根目錄下本地開發(fā)沒問題一換環(huán)境就廢。解決把上傳路徑改成本機固定目錄讓 Tomcat 通過配置的映射訪問。比如圖片存在D:/canteen_img/在 spring-mvc.xml 里加一個資源映射配置把/img/**指向這個本地目錄。這樣圖片不依賴項目部署目錄重新發(fā)布工程也不會丟。數(shù)據(jù)庫里存的還是相對路徑/img/xx.jpg頁面上不需要改動。5.4 Tomcat 啟動后自動停止沒有任何有效報錯現(xiàn)象啟動日志刷到一半突然沒有動靜控制臺退出到可以輸入命令的狀態(tài)像是 Tomcat 進程被殺掉。原因內(nèi)存不夠或配置的 JVM 參數(shù)有問題。老畢設項目用 JDK 8 和 Eclipse 同時跑默認內(nèi)存被 IDE 占掉太多。另外有時殺毒軟件會攔截 Tomcat 的某些操作導致進程被強制結(jié)束。解決在 Eclipse 的 Tomcat 啟動配置里加 JVM 參數(shù)-Xms256m -Xmx512m給足運行內(nèi)存。同時檢查系統(tǒng)環(huán)境變量有沒有CATALINA_HOME指向了別的 Tomcat 版本如果有先刪掉再用 Eclipse 內(nèi)部配置啟動??刂婆_如果沒有打出 HTTP 端口監(jiān)聽成功的日志基本可以確定是進程級問題跟代碼無關。5.5 訂單提交成功但后臺看不到訂單現(xiàn)象前臺用戶下單提示成功管理員登錄后臺訂單管理列表里卻沒有任何記錄。原因最常見的原因是用戶和管理員使用了不同的數(shù)據(jù)庫。比如你自己手動新開了一個數(shù)據(jù)庫連接往另一個庫插了測試數(shù)據(jù)而后臺界面連接的是原始庫。也有可能是事務沒提交Transactional注解加在類上但方法沒有正確掃描到。解決先確認前臺后臺連的是同一個 MySQL 庫直接執(zhí)行 SQL 查SELECT * FROM orders;看數(shù)據(jù)到底有沒有落庫。如果庫里確實有記錄但頁面不顯示去查訂單管理的查詢 SQL 是否有狀態(tài)過濾條件比如默認只查 status0 的訂單可你改狀態(tài)之后它就不會再出現(xiàn)在篩選結(jié)果里。把查詢條件打印出來看一眼比翻半天代碼管用。6. 演示技巧用一條“下單鏈路”講清全項目答辯演示和平時跑功能不太一樣時間有限不能把每個菜單都點一遍。我復盤了自己那次的演示順序覺得最有效率的就是圍繞“用戶下單 → 后臺接單”這條主線走一條鏈路把用戶管理、菜品管理、訂單管理三個核心模塊串起來。演示前先在系統(tǒng)里準備好兩組賬號一組普通用戶一組管理員。登錄普通用戶打開某個食堂的菜品列表選一道菜提交訂單這一步展示了前臺 JSP 列表渲染和訂單提交。切到管理員賬號進入訂單管理把訂單狀態(tài)從“待接單”改成“已接單”這一步展示了狀態(tài)字段的作用和后臺處理流程。整個演示三分半鐘覆蓋了三個核心角色和核心表關系。如果老師追問“訂單狀態(tài)是怎么控制的”直接打開數(shù)據(jù)庫或者 Mapper 里看一眼 status 字段把四個取值列出來0 待接單、1 已接單、2 已完成、3 已取消。然后順手演示一下取消訂單——前臺用戶把狀態(tài)為 0 的訂單取消后臺列表里這條訂單就變成已取消。這個細節(jié)會讓老師覺得你不只是跑通了頁面還真的理解了狀態(tài)機的概念。我建議在正式演示前把“用戶下單”和“管理員改狀態(tài)”完整走三遍中間不要干任何多余操作。第一次在干凈的數(shù)據(jù)庫上走確認所有初始數(shù)據(jù)正常第二次在頁面停留比較長的緩沖時間防止某個圖片加載慢導致頁面卡頓第三次模擬老師突然提問的狀態(tài)比如“如果食堂下架了這道菜之前下的訂單還在嗎”現(xiàn)場演示用訂單快照字段回答。這套資源里附帶數(shù)據(jù)庫腳本、論文和答辯 PPT拿到后建議先把論文里的需求分析部分和代碼里的實際功能對齊一遍因為答辯老師經(jīng)常拿著論文里的功能列表讓你現(xiàn)場演示。如果論文里寫了“菜品評論功能”而代碼里沒實現(xiàn)那就在答辯前把論文里的功能描述改掉或者把代碼補齊二選一絕不能留這么一個明顯的口頭漏洞。從那以后我每次準備這類系統(tǒng)演示都強制先走一遍“用戶注冊到訂單完成”的鏈路再談其他確保主心骨是通的希望這個習慣也能幫到你。本文還有配套的精品資源點擊獲取