員積分管理系統(tǒng)課設(shè)資源解析與部署指南)
簡(jiǎn)介一套基于 Java 實(shí)現(xiàn)的超市積分管理系統(tǒng)項(xiàng)目資料定位清晰適合 Java Web 課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)以及想了解企業(yè)級(jí)分層開發(fā)的初學(xué)者。系統(tǒng)圍繞會(huì)員、商品與積分等核心業(yè)務(wù)展開采用 MVC 設(shè)計(jì)思想并用 Servlet 處理請(qǐng)求、JSP 生成動(dòng)態(tài)頁面、JDBC 完成數(shù)據(jù)庫訪問配合 DAO 模式將數(shù)據(jù)操作與業(yè)務(wù)邏輯解耦代碼結(jié)構(gòu)清晰。壓縮包共 5 個(gè)文件包括源代碼壓縮包、項(xiàng)目截圖壓縮包、數(shù)據(jù)庫腳本、項(xiàng)目報(bào)告文檔和說明文本整體大小約 18.21MB目錄組織便于快速定位。目前已有 360 人學(xué)習(xí)下載。使用時(shí)可先導(dǎo)入 SQL 腳本建立數(shù)據(jù)環(huán)境再通過源碼理解各功能模塊的實(shí)現(xiàn)思路項(xiàng)目報(bào)告對(duì)需求分析、系統(tǒng)設(shè)計(jì)與測(cè)試過程有詳細(xì)記錄截圖則展示了實(shí)際界面效果能夠幫助使用者完成從環(huán)境搭建、功能復(fù)現(xiàn)到答辯匯報(bào)的完整流程。1. 基于 Java 的超市積分管理系統(tǒng)這套資源包到底解決什么問題在“基于 Java 的超市會(huì)員積分管理系統(tǒng)”這個(gè)題目前面這套壓縮包一次性給全了數(shù)據(jù)庫腳本 jf.sql、源代碼 jf.zip、項(xiàng)目報(bào)告、答辯 PPT 和項(xiàng)目截圖算是課設(shè)資源里少見的結(jié)構(gòu)完整的版本。第一次拿到先別急著解壓找 README先把包里這幾樣?xùn)|西的用途對(duì)清楚數(shù)據(jù)庫決定數(shù)據(jù)從哪來源代碼決定業(yè)務(wù)邏輯怎么寫報(bào)告和 PPT 決定答辯時(shí)你能講出多少東西。這類資源真正解決的問題是“完整 Java Web 項(xiàng)目長(zhǎng)什么樣”。對(duì)還在做課設(shè)的同學(xué)來說最大的障礙不是寫不出積分換算算法而是不知道 Servlet、DAO、JSP 之間怎么組織代碼對(duì)想往簡(jiǎn)歷上補(bǔ)一個(gè)業(yè)務(wù)場(chǎng)景的初級(jí)開發(fā)者來說難點(diǎn)則是積分流水、會(huì)員信息、商品數(shù)據(jù)這些表要怎么設(shè)計(jì)才不返工。這套資源把兩件事都攤開放在眼前你可以先跑通它再照著它的分層結(jié)構(gòu)和表設(shè)計(jì)改成自己的版本。2. 源碼與數(shù)據(jù)庫拆解MVC 分層、DAO 封裝和業(yè)務(wù)表設(shè)計(jì)2.1 從包結(jié)構(gòu)看分層Servlet 當(dāng)控制器DAO 管數(shù)據(jù)把 jf.zip 解壓后用 IDEA 打開項(xiàng)目根包一般叫 com.supermarket 或者類似的命名下面按職責(zé)分成 entity、dao、servlet、util、filter 幾個(gè)子包。這種結(jié)構(gòu)在 Java Web 課程設(shè)計(jì)里幾乎成了標(biāo)準(zhǔn)套路實(shí)體類對(duì)應(yīng)數(shù)據(jù)庫表字段DAO 負(fù)責(zé)所有 SQL 操作Servlet 接收瀏覽器請(qǐng)求后調(diào)用 DAOJSP 只做頁面渲染不寫業(yè)務(wù)邏輯。看代碼前先把這個(gè)對(duì)應(yīng)關(guān)系記在腦子里后面無論看哪個(gè)文件都不會(huì)迷路。數(shù)據(jù)庫連接這個(gè)“地基”通常放在 util 包里命名為 DBUtil。常見寫法是靜態(tài)代碼塊加載驅(qū)動(dòng)再用 getConnection() 返回連接同時(shí)提供一個(gè) close() 方法回收資源public class DBUtil { private static final String URL jdbc:mysql://localhost:3306/jf?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8; private static final String USER root; private static final String PASSWORD 123456; static { try { Class.forName(com.mysql.jdbc.Driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt ! null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn ! null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }這里有兩個(gè)關(guān)鍵細(xì)節(jié)。第一URL 里的 serverTimezoneAsia/Shanghai 是給 MySQL 8.0 以上驅(qū)動(dòng)用的老版本不加也能跑但新驅(qū)動(dòng)不加會(huì)在獲取連接時(shí)直接拋時(shí)區(qū)異常。第二close() 方法要按 ResultSet、Statement、Connection 的順序關(guān)閉順序反了數(shù)據(jù)庫連接池里的連接很容易泄漏系統(tǒng)跑一段時(shí)間后就會(huì)出現(xiàn)連接不夠用的報(bào)錯(cuò)。DAO 層的常見做法是每張表一個(gè) DAO 類MemberDao 負(fù)責(zé)會(huì)員表的增刪改查PointsRecordDao 負(fù)責(zé)積分流水表。每個(gè) DAO 里就是標(biāo)準(zhǔn)的 JDBC 五步加載驅(qū)動(dòng)、獲取連接、預(yù)編譯 SQL、執(zhí)行、關(guān)閉資源。這種“一張表一個(gè) DAO”的做法雖然樸素但做課設(shè)足夠了而且后續(xù)哪怕?lián)Q成 MyBatisSQL 語句本身也是可以直接遷移的。2.2 jf.sql 數(shù)據(jù)庫設(shè)計(jì)會(huì)員、商品、積分流水三張主表把 jf.sql 用文本編輯器打開先通讀所有建表語句。從這種課設(shè)項(xiàng)目的通用設(shè)計(jì)來看核心表通常是下面這四類你可以在自己的數(shù)據(jù)庫里對(duì)照確認(rèn)表名作用關(guān)鍵字段member會(huì)員基本信息id、username、password、total_pointspoints_record積分流水記錄id、member_id、change_type、points、remark、create_timegoods商品信息id、goods_name、price、stockadmin管理員賬號(hào)id、username、password會(huì)員表建表語句常見長(zhǎng)這樣CREATE TABLE member ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(50) NOT NULL, real_name VARCHAR(50), phone VARCHAR(20), total_points INT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP );積分流水表是整套系統(tǒng)的對(duì)賬關(guān)鍵一般會(huì)定義 change_type 字段來區(qū)分積分是獲得還是消費(fèi)CREATE TABLE points_record ( id INT PRIMARY KEY AUTO_INCREMENT, member_id INT NOT NULL, change_type TINYINT COMMENT 1-獲得 2-消費(fèi) 3-過期, points INT NOT NULL, remark VARCHAR(255), create_time DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (member_id) REFERENCES member(id) );看建表語句時(shí)我建議你把重心放在兩個(gè)地方。一是字符集是不是統(tǒng)一用的 utf8mb4如果建表語句里沒寫 DEFAULT CHARSETutf8mb4導(dǎo)入后中文大概率亂碼。二是外鍵關(guān)聯(lián)積分流水表的 member_id 是否和 member 表建立了正確聯(lián)系這決定了后面按會(huì)員查明細(xì)時(shí)能不能用一條 JOIN 語句搞定。這里還要解釋一個(gè)業(yè)務(wù)常識(shí)為什么積分系統(tǒng)一定要有流水表只維護(hù) member 表里的 total_points更新一下總值不就行了從功能演示的角度確實(shí)行但真實(shí)業(yè)務(wù)里會(huì)員積分對(duì)不上賬時(shí)沒有任何明細(xì)可以追溯。這也是答辯時(shí)老師特別愛追問的點(diǎn)你要能說出“流水表記錄每一次變動(dòng)、會(huì)員表只存匯總值兩個(gè)表配合才能對(duì)賬”這句話這道題基本就穩(wěn)了。2.3 為什么不直接用框架Servlet/JSP 組合的學(xué)習(xí)價(jià)值有人會(huì)困惑現(xiàn)在公司里都寫 Spring Boot為什么這種課程設(shè)計(jì)還是 Servlet JSP原因很直接課程設(shè)計(jì)考察的是 Web 原理。Servlet 是 Java Web 的根JSP 是視圖層的老牌方案把這個(gè)組合跑通你才真正理解 HTTP 請(qǐng)求怎么進(jìn)服務(wù)端、response 怎么回瀏覽器。后面再上手 Spring MVC看到 DispatcherServlet 會(huì)非常親切因?yàn)樗旧砭褪墙⒃?Servlet 規(guī)范之上的一層封裝。所以拆這套源碼的時(shí)候不要抱著“這代碼真老”的心態(tài)去看而是帶著“它在教科書里長(zhǎng)什么樣”的心態(tài)。答辯時(shí)你也可以主動(dòng)講一句“我這里的 Servlet 本質(zhì)上就是 Controller后續(xù)可以平滑遷移到 Spring MVC?!边@句話在不少老師那里是加分的因?yàn)檎f明你不是只會(huì)抄代碼而是看懂了分層本質(zhì)。3. 把項(xiàng)目跑起來環(huán)境配置、數(shù)據(jù)庫導(dǎo)入與部署步驟3.1 本地環(huán)境怎么搭JDK、Tomcat、MySQL 版本匹配能穩(wěn)定跑通這套 Java Web 課設(shè)的環(huán)境組合常見的是 JDK 8 Tomcat 8.5/9 MySQL 5.7 或 MySQL 8.0。版本要稍微對(duì)齊否則會(huì)出現(xiàn)驅(qū)動(dòng)類和 JDK 版本不匹配的報(bào)錯(cuò)。我的個(gè)人習(xí)慣是 JDK 8 配 Tomcat 8.5MySQL 用 5.7這套組合與多數(shù)課設(shè)代碼的年代最接近翻車率最低。如果你本機(jī)已經(jīng)裝了高版本 JDK比如 JDK 17項(xiàng)目里某些用了舊 API 的代碼可能會(huì)編譯不過。這種情況不要硬調(diào) JDK 版本更好的做法是在 IDEA 里用 Project Structure 單獨(dú)給項(xiàng)目指定 JDK 8不影響系統(tǒng)全局環(huán)境。3.2 導(dǎo)入 jf.sql命令行和可視化工具兩條路MySQL 5.7 導(dǎo)入最干凈的方式是命令行先確認(rèn) MySQL 服務(wù)已啟動(dòng)再執(zhí)行mysql -u root -p jf.sql如果 jf.sql 里沒有包含 CREATE DATABASE 語句需要先手動(dòng)建庫再導(dǎo)入mysql -u root -p -e CREATE DATABASE jf DEFAULT CHARACTER SET utf8mb4; mysql -u root -p jf jf.sql這兩條命令的意思分別是建一個(gè)名為 jf 的數(shù)據(jù)庫并指定 utf8mb4 字符集然后把 jf.sql 里的建表和數(shù)據(jù)導(dǎo)入 jf 庫。注意第二條命令的 jf 參數(shù)表示選中數(shù)據(jù)庫如果漏了它所有表都會(huì)建到默認(rèn)庫里項(xiàng)目就連不上了。用 Navicat 的話邏輯一樣右鍵連接下的數(shù)據(jù)庫選擇“運(yùn)行 SQL 文件”選中 jf.sql然后把選項(xiàng)里的“遇到錯(cuò)誤時(shí)停止”關(guān)閉。這個(gè)選項(xiàng)開著時(shí)一個(gè)字符集級(jí)別的警告就可能讓整個(gè)導(dǎo)入中斷實(shí)際 SQL 本身可能并沒有致命問題。3.3 修改數(shù)據(jù)庫連接參數(shù)DBUtil 與配置文件導(dǎo)入數(shù)據(jù)庫后代碼里的連接信息不一定和你本機(jī)匹配。默認(rèn)密碼如果不是 123456你逐個(gè)翻文件找會(huì)很浪費(fèi)時(shí)間。最快的方式是直接在 IDEA 里全局搜索 jdbc:mysql定位到 DBUtil.java 或者 src 目錄下的 db.properties、jdbc.propertiesjdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/jf?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password你的密碼改完配置文件后IDEA 的 target 目錄會(huì)自動(dòng)同步不用手動(dòng)重啟編譯。這里想強(qiáng)調(diào)的一點(diǎn)是很多同學(xué)只改密碼不改 URL 里的庫名結(jié)果 jf.sql 導(dǎo)入到了叫 test 的庫里代碼卻還連 jf 庫報(bào)了“Table doesnt exist”的錯(cuò)誤。用項(xiàng)目之前把“數(shù)據(jù)庫名、賬號(hào)、密碼”這三個(gè)參數(shù)同時(shí)統(tǒng)一好后面能省出至少一小時(shí)排錯(cuò)時(shí)間。把 jf.zip 解壓時(shí)還要注意一點(diǎn)不要用系統(tǒng)自帶的解壓功能直接雙擊打開那樣全中文文件名在某些 Windows 版本下會(huì)出現(xiàn)編碼問題。建議用 7-Zip 或 WinRAR 解壓到?jīng)]有中文的路徑比如 D:\jf-project然后整個(gè)路徑盡量避免中文字符不然 Tomcat 部署階段偶爾會(huì)出現(xiàn)奇怪的路徑解析問題。3.4 IDEA 配置 Tomcat 并啟動(dòng)war exploded 是關(guān)鍵IDEA 里部署 Web 項(xiàng)目的標(biāo)準(zhǔn)流程是Run → Edit Configurations → 點(diǎn)加號(hào)選 Tomcat Server → Local然后在 Deployment 頁簽添加 Artifact選 war exploded 格式Application context 填 /jf。這里學(xué)生的常見誤操作是添加了 Artifact 但忘記設(shè)置 context或者直接用了 war 包格式導(dǎo)致修改代碼后要反復(fù)重新打包開發(fā)效率極低。war exploded 的意思是“解壓后的目錄”開發(fā)時(shí)改 JSP 頁面和資源文件刷新瀏覽器就能看到效果不需要重新打 war 包。配置好之后啟動(dòng) Tomcat瀏覽器訪問 http://localhost:8080/jf/如果能看到登錄頁面說明項(xiàng)目骨架已經(jīng)活了。4. 核心業(yè)務(wù)實(shí)現(xiàn)積分累計(jì)、積分消費(fèi)與流水查詢4.1 登錄與權(quán)限管理員和會(huì)員兩種身份怎么區(qū)分從功能列表看系統(tǒng)首先要解決的是登錄。admin 表存管理員member 表存會(huì)員登錄時(shí) Servlet 先根據(jù)頁面提交的賬號(hào)去查對(duì)應(yīng)表比對(duì)密碼通過后把用戶對(duì)象放進(jìn) session。之后 JSP 頁面通過判斷 session 里的用戶身份決定顯示管理員菜單還是會(huì)員菜單。登錄邏輯的典型寫法String username request.getParameter(username); String password request.getParameter(password); Member member memberDao.findByUsername(username); if (member ! null member.getPassword().equals(password)) { session.setAttribute(loginUser, member); response.sendRedirect(index.jsp); } else { request.setAttribute(error, 用戶名或密碼錯(cuò)誤); request.getRequestDispatcher(login.jsp).forward(request, response); }這段代碼值得注意的點(diǎn)是密碼比對(duì)方式。課設(shè)項(xiàng)目直接用明文比對(duì)很常見因?yàn)檠菔痉奖愕绻@個(gè)項(xiàng)目要寫進(jìn)簡(jiǎn)歷你至少該補(bǔ)一層 MD5 加鹽。面試官如果看到你簡(jiǎn)歷里寫的是 Java 項(xiàng)目問到用戶密碼安全你的回答如果只是“明文存”印象分會(huì)差很多。4.2 積分累計(jì)消費(fèi)金額怎么換算成積分積分累計(jì)是整套系統(tǒng)的核心業(yè)務(wù)。假設(shè)規(guī)則是“消費(fèi)每滿 10 元累計(jì) 1 積分”那在結(jié)賬動(dòng)作里要同時(shí)完成兩件事更新 member 表的 total_points再往 points_record 表插入一條獲得明細(xì)。事務(wù)控制是這里最容易翻車的點(diǎn)沒加事務(wù)的話更新了總分但沒寫入流水或者寫了流水但總分沒變都會(huì)讓數(shù)據(jù)對(duì)不上。參考實(shí)現(xiàn)public void addPoints(int memberId, double amount) { int points (int) Math.floor(amount / 10); if (points 0) return; Connection conn null; PreparedStatement ps1 null; PreparedStatement ps2 null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); ps1 conn.prepareStatement(UPDATE member SET total_points total_points ? WHERE id ?); ps1.setInt(1, points); ps1.setInt(2, memberId); ps1.executeUpdate(); ps2 conn.prepareStatement(INSERT INTO points_record(member_id, change_type, points, remark) VALUES(?, 1, ?, 消費(fèi)積分)); ps2.setInt(1, memberId); ps2.setInt(2, points); ps2.executeUpdate(); conn.commit(); } catch (SQLException e) { if (conn ! null) { try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { DBUtil.close(conn, ps1, null); DBUtil.close(null, ps2, null); } }這段代碼里有三個(gè)可以展開講的設(shè)計(jì)。第一Math.floor 向下取整9.9 元的消費(fèi)不會(huì)給你算出 1 積分這符合業(yè)務(wù)直覺。第二setAutoCommit(false) 開啟手動(dòng)事務(wù)commit 和 rollback 的配對(duì)保證兩個(gè)操作要么都成功要么都失敗這是數(shù)據(jù)庫原子性的實(shí)際應(yīng)用。第三PreparedStatement 預(yù)編譯可以有效防止 SQL 注入JDBC 時(shí)代這個(gè)考點(diǎn)幾乎每次都會(huì)被問到你脫口答出來會(huì)顯得基礎(chǔ)很扎實(shí)。4.3 積分消費(fèi)與流水查詢對(duì)賬邏輯怎么閉環(huán)積分消費(fèi)是反方向操作。會(huì)員用積分抵扣金額時(shí)積分余額減少同時(shí)寫一條 change_type2 的記錄。查詢積分流水時(shí)頁面通常是一個(gè)表格列出每次變動(dòng)的時(shí)間、類型、積分?jǐn)?shù)和備注典型 SQL 是SELECT * FROM points_record WHERE member_id ? ORDER BY create_time DESC;這條 SQL 按會(huì)員 ID 過濾后按時(shí)間倒序排列保證最新變動(dòng)排在最上面。拿到 ResultSet 后循環(huán)渲染到 JSP 表格里這就是一個(gè)完整的“DAO 查詢 → Servlet 轉(zhuǎn)發(fā) → JSP 展示”鏈路。為什么要強(qiáng)調(diào)流水查詢這個(gè)功能因?yàn)榇疝q時(shí)老師特別喜歡問“積分系統(tǒng)怎么防止會(huì)員惡意刷積分”你只要能說出“每一筆變動(dòng)都有流水記錄前端只展示積分匯總后臺(tái)可按會(huì)員查明細(xì)”這個(gè)問題就答到點(diǎn)子上了。數(shù)據(jù)一致性在這里靠的不是什么高深算法而是“先建流水表、再動(dòng)總分”的順序約定加一個(gè)事務(wù)兜底。5. 避坑與常見問題啟動(dòng)、部署、答辯里的高頻坑5.1 數(shù)據(jù)庫連接報(bào) Access denied 或 Public Key Retrieval現(xiàn)象Tomcat 啟動(dòng)不報(bào)錯(cuò)但訪問登錄頁提交后提示 Access denied for user rootlocalhost (using password: YES)或者直接報(bào) Communications link failure。原因數(shù)據(jù)庫密碼和代碼里的連接參數(shù)不一致或者 MySQL 8.0 默認(rèn)使用 caching_sha2_password 認(rèn)證插件老驅(qū)動(dòng)首次連接時(shí)無法自動(dòng)完成公鑰檢索。解決先改 DBUtil 或 db.properties 里的密碼如果用的 MySQL 8.0就在連接 URL 末尾追加 allowPublicKeyRetrievaltrueuseSSLfalse再把數(shù)據(jù)庫用戶的認(rèn)證插件改成 mysql_native_password。命令是 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密碼;執(zhí)行完后重啟 Tomcat。5.2 頁面中文全部變成問號(hào)現(xiàn)象登錄后頁面顯示??? 或者繁體亂碼數(shù)據(jù)庫里看中文數(shù)據(jù)也全是亂碼。原因數(shù)據(jù)庫連接字符集沒指定或者 JSP/Servlet 沒有統(tǒng)一編碼過濾器也可能是建庫時(shí)沒指定 utf8mb4。解決建庫時(shí)強(qiáng)制 DEFAULT CHARACTER SET utf8mb4JDBC URL 里帶 characterEncodingutf8項(xiàng)目里加上一個(gè) CharacterEncodingFilter把 request 和 response 的編碼都設(shè)置成 UTF-8。檢查順序是從數(shù)據(jù)庫到代碼再到頁面逐層排除一般都能定位到是某一步?jīng)]做編碼統(tǒng)一。5.3 部署后一直 404訪問不到項(xiàng)目頁面現(xiàn)象IDEA 配置 Tomcat 后訪問 localhost:8080 能看到 Tomcat 歡迎頁但訪問 /jf/ 顯示 404。原因Deployment 里沒有添加 Artifact或者 Application context 設(shè)置成了 /導(dǎo)致項(xiàng)目沒有掛載到預(yù)期路徑。解決Run → Edit Configurations → Deployment 頁簽添加 Artifact選 war exploded把 Application context 改為 /jf保存后重啟。重啟后看控制臺(tái)日志里是否有 “Deployment of web application archive” 這一行有這一行說明部署成功純粹是路徑問題。5.4 代碼導(dǎo)入 IDEA 后大量紅叉報(bào)錯(cuò)現(xiàn)象打開項(xiàng)目后一堆 import 語句標(biāo)紅提示找不到包或 JDK 版本錯(cuò)誤。原因IDEA 沒有正確識(shí)別這個(gè)項(xiàng)目的 SDK或者項(xiàng)目本身不是 Maven 工程依賴庫沒有自動(dòng)下載。解決File → Project Structure → Project SDK 選擇 JDK 8Modules 里確認(rèn) Sources 路徑如果項(xiàng)目里有 pom.xml右鍵點(diǎn) Maven → Reload Project。還有一種情況是 lib 目錄下的 jar 包沒有加到模塊依賴?yán)镄枰?Modules → Dependencies 手動(dòng)添加 jar 包。這兩種情況按順序檢查紅線基本都能消掉。5.5 答辯時(shí)被問“為什么用 Servlet 不用框架”現(xiàn)象老師看完代碼后問現(xiàn)在都用 Spring Boot你為什么用 Servlet原因老師想確認(rèn)你是真的理解底層原理還是只會(huì)套框架。解決如實(shí)說明課設(shè)考察點(diǎn)是 Web 原理和 MVC 分層然后強(qiáng)調(diào) Servlet 本身就是 MVC 里的 Controller并且你項(xiàng)目里的 DAO 層以后可以平滑遷移到 Spring Boot。如果能在這個(gè)回答后補(bǔ)一句“Spring MVC 的 DispatcherServlet 就是基于 Servlet 規(guī)范封裝的”這個(gè)問題就變成了加分題。6. 從復(fù)現(xiàn)到改造答辯講解與二次開發(fā)技巧6.1 答辯講解按數(shù)據(jù)流走不要按目錄念 PPT答辯 PPT 里通常有項(xiàng)目背景、需求分析、系統(tǒng)設(shè)計(jì)、功能演示這些章節(jié)但照著順序念是新手最容易踩的坑。我的習(xí)慣是畫一條業(yè)務(wù)數(shù)據(jù)流主線登錄 → 查詢會(huì)員 → 累計(jì)積分 → 消費(fèi)積分 → 查看流水。這條線走完老師基本就明白系統(tǒng)做了什么再回頭講表結(jié)構(gòu)和分層設(shè)計(jì)邏輯就會(huì)非常順。項(xiàng)目報(bào)告和截圖建議提前對(duì)照看一遍。截圖是你說服別人的最直接證據(jù)運(yùn)行界面里如果能看到積分流水列表、扣減前后的余額變化比任何文字都管用。答辯前至少完整跑一遍所有功能把“輸入什么 → 數(shù)據(jù)庫變化了什么 → 頁面展示了什么”這三個(gè)觀察點(diǎn)記住。6.2 二次開發(fā)加功能從加訂單表到遷移 Spring Boot這個(gè)項(xiàng)目最值得改的方向是加一張訂單表把積分累計(jì)和消費(fèi)都關(guān)聯(lián)到訂單上下文。常見做法是建 order 表和 order_item 明細(xì)表積分規(guī)則表單獨(dú)抽出來這樣“消費(fèi)多少、按什么比例換算、積分什么時(shí)候到賬”就不再是寫死的常量而是可配置的業(yè)務(wù)規(guī)則。這個(gè)改動(dòng)不大但能讓系統(tǒng)的可解釋性提升一個(gè)檔次。如果有余力可以嘗試把 DAO 層換掉租用一段實(shí)踐 Spring Boot MyBatis 的遷移經(jīng)歷。你會(huì)發(fā)現(xiàn)原來寫的 SQL 基本都是能復(fù)用的只要把 JDBC 模板換成 Mapper 接口就行。這個(gè)過程本身就是一次很好的 Java 基礎(chǔ)復(fù)習(xí)從 Servlet 到 Spring Boot 的跳躍不會(huì)太突兀。從那以后我拆這種課設(shè)壓縮包第一件事一定是先看數(shù)據(jù)庫腳本和說明文檔而不是先解壓代碼。數(shù)據(jù)庫表能建出來業(yè)務(wù)邏輯就完成了一半代碼和庫對(duì)不上跑起來全是坑。這個(gè)習(xí)慣幫我跳過了至少五六個(gè)版本的課設(shè)項(xiàng)目排錯(cuò)也希望你能在拿到這套資源后少走這一步彎路。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取