上銀行系統(tǒng)源碼拆包:MVC分層與事務管理實戰(zhàn))
簡介本資源為基于JavaWeb開發(fā)的個人網(wǎng)上銀行系統(tǒng)完整項目包采用MVC模式分層設計面向計算機相關專業(yè)的在校學生、教師及企業(yè)開發(fā)者可用于畢業(yè)設計、課程設計、大作業(yè)或初期項目立項演示。壓縮包共368個文件約64.8MB包含52個Java源文件、31個JSP頁面、84個JavaScript腳本、48個CSS樣式及83張PNG截圖另附數(shù)據(jù)庫SQL腳本、項目報告文檔與系統(tǒng)截圖覆蓋登錄、存款、轉賬、定期存款、活期轉定期、信息展示及日志查看等核心功能模塊。項目代碼均經(jīng)過功能驗證可穩(wěn)定運行并配有需求分析、總體設計、詳細設計、數(shù)據(jù)庫設計與測試說明便于讀者理解MVC架構與銀行業(yè)務邏輯。目前已有147人學習下載適合作為入門進階參考或二次開發(fā)基礎。1. 個人網(wǎng)上銀行系統(tǒng)源碼拆包一套能跑通存轉定期的 JavaWeb 畢設很多同學做畢業(yè)設計時最頭疼的不是寫不出代碼而是找不到一套結構完整、能跑通、還帶報告和截圖的參考項目。這套基于 JavaWeb 的個人網(wǎng)上銀行系統(tǒng)正好卡在這個需求點上——它用 MVC 模式把用戶登錄、存款、轉賬、定期存款、活期轉定期、日志查看這些銀行核心業(yè)務串了起來附帶數(shù)據(jù)庫腳本、設計報告和系統(tǒng)截圖。適合計算機相關專業(yè)的在校生做課程設計或畢設也適合剛接觸 JavaWeb 想找一個完整案例練手的開發(fā)者。下面我從拆包結構、環(huán)境搭建、核心功能實現(xiàn)到踩坑排查把這份資源完整過一遍。2. 拆包看結構MVC 分層與數(shù)據(jù)庫表怎么對應拿到壓縮包先別急著導入 IDE花十分鐘把目錄結構和數(shù)據(jù)庫腳本對一遍后面能省掉大量返工。這套項目用的是經(jīng)典 MVC 三層架構配合 JSP 做視圖層Servlet 做控制層JavaBean DAO 做模型層前端還引了 Bootstrap、FontAwesome、Summernote、Datepicker 這些靜態(tài)資源。2.1 目錄結構與技術棧清單解壓后大致會看到這么幾塊內(nèi)容目錄/文件作用技術點src/Java 源碼Servlet、JavaBean、DAO、工具類WebContent/ 或 webapp/前端資源JSP、CSS、JS、字體圖標sql/ 或 db/數(shù)據(jù)庫腳本MySQL 建表與初始數(shù)據(jù)報告文檔設計說明需求分析、詳細設計、測試截圖目錄運行效果各功能頁面截圖前端資源里能看到fontawesome-webfont.svg_v4.3.0、fontawesome-webfont.ttf_v4.3.0、fontawesome-webfont.woff_v4.3.0、fontawesome-webfont.eot_v4.3.0、fontawesome-webfont.woff2_v4.3.0這一整套字體文件說明圖標用的是 FontAwesome 4.3.0。樣式表里有bootstrap.min.css、animate.css、datepicker3.css、summernote-bs3.css、style.css基本可以判斷前端是 Bootstrap 3 jQuery 那一套日期選擇用 bootstrap-datepicker富文本編輯用 Summernote。這套組合在當年的課程設計里非常主流兼容性好改起來也順手。提示如果解壓后看到_v4.3.0這種帶下劃線和等號的文件名是某些下載工具或服務器給靜態(tài)資源加的版本參數(shù)直接重命名去掉_v4.3.0后綴即可否則 CSS 里引用字體時可能 404。2.2 數(shù)據(jù)庫表與業(yè)務功能的映射關系銀行系統(tǒng)的核心在數(shù)據(jù)庫設計。根據(jù)報告里的功能清單至少需要這么幾張表用戶表user存登錄賬號、密碼、姓名、身份證、聯(lián)系方式對應登錄功能。賬戶表account存卡號、余額、賬戶類型活期/定期、開戶時間對應存款和查詢。交易記錄表transaction存流水號、卡號、交易類型、金額、交易時間、備注對應轉賬、存取款、日志查看。定期存款表deposit存定期單號、卡號、本金、利率、存期、到期日對應定期存款和活期轉定期。建表時注意金額字段用DECIMAL(15,2)而不是FLOAT這是血淚經(jīng)驗——浮點數(shù)在多次加減后會出現(xiàn)精度丟失銀行系統(tǒng)里一分錢的誤差都是事故。交易時間用DATETIME別用TIMESTAMP后者有 2038 年上限雖然課程設計跑不到那時候但習慣要養(yǎng)好。CREATE TABLE account ( card_no VARCHAR(20) PRIMARY KEY, user_id INT NOT NULL, balance DECIMAL(15,2) DEFAULT 0.00, account_type VARCHAR(10) DEFAULT 活期, open_time DATETIME DEFAULT CURRENT_TIMESTAMP, status TINYINT DEFAULT 1 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;這段建表語句里card_no做主鍵是因為卡號本身唯一且業(yè)務查詢頻繁balance用DECIMAL保證金額精確status字段用來做賬戶凍結/注銷的軟刪除比物理刪除安全。ENGINEInnoDB是為了支持事務轉賬操作必須在一個事務里完成扣款和入賬否則中途失敗會出現(xiàn)單邊賬。3. 環(huán)境搭建與項目導入從 JDK 到 Tomcat 的完整鏈路環(huán)境配置是新手翻車最多的地方。這套項目是傳統(tǒng) JavaWeb 項目不是 Spring Boot所以沒有內(nèi)嵌服務器必須自己配 Tomcat。下面按順序走一遍。3.1 JDK、Tomcat、MySQL 版本選擇版本不匹配是啟動失敗的頭號原因。根據(jù)項目年代和技術棧推薦這套組合組件推薦版本說明JDK1.8高版本 JDK 編譯老項目容易出兼容問題Tomcat8.5 或 9.0別用 Tomcat 10包名從 javax 變 jakarta 會全紅MySQL5.7 或 8.08.0 需要改驅動類和連接串IDEIDEA 或 EclipseIDEA 需配 Web 模塊和 ArtifactsTomcat 10 是最大的坑。它把 Servlet API 的包名從javax.servlet改成了jakarta.servlet這套老項目的 import 全是 javax換 Tomcat 10 直接編譯不過。我一般會先確認項目里 import 的是哪個包再決定 Tomcat 版本。3.2 IDEA 導入與 Artifacts 配置IDEA 導入傳統(tǒng) JavaWeb 項目的關鍵在 Project Structure 里配三樣東西SDK、Web 模塊、Artifacts。# 第一步確認 JDK 版本 java -version # 輸出應為 1.8.x # 第二步確認 MySQL 服務在跑 mysql -u root -p -e SELECT VERSION(); # 第三步導入數(shù)據(jù)庫腳本 mysql -u root -p bank_db sql/bank_db.sql導入腳本后打開 IDEAFile → Project StructureProjectSDK 選 1.8Language level 選 8。Modules確認 src 被標記為 SourcesWebContent 或 webapp 被標記為 Web Resource Directoryweb.xml 路徑指對。Artifacts新增 Web Application: Exploded把編譯輸出和 Web 資源都加進去。Run/Debug Configurations新增 Tomcat LocalDeployment 里選剛才的 ArtifactApplication context 設成/bank。配置完啟動瀏覽器訪問http://localhost:8080/bank/能看到登錄頁就成功了一半。3.3 數(shù)據(jù)庫連接配置與驅動項目里通常有個db.properties或直接在工具類里寫死連接信息。找到它改成自己的jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/bank_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password你的密碼MySQL 8.0 的驅動類是com.mysql.cj.jdbc.Driver5.7 是com.mysql.jdbc.Driver寫錯會報ClassNotFoundException。連接串里的serverTimezone必須加否則 8.0 會報時區(qū)錯誤。useSSLfalse是關掉 SSL 警告本地開發(fā)用不上。如果項目用的是連接池常見的是 Druid 或 C3P0還要檢查連接池配置文件里的 URL 和賬號密碼是否同步改了。注意改完配置后一定要重新 Build Artifacts否則 Tomcat 跑的還是舊的 class 文件改了等于沒改。4. 核心功能實現(xiàn)登錄、存款、轉賬、定期存款的代碼邏輯功能實現(xiàn)是這套項目的價值所在。報告里列了登錄、存款、刪除、修改、查詢、信息展示、轉賬、定期存款、查看日志、活期轉定期這些模塊我挑幾個最核心的講清楚代碼邏輯和參數(shù)設計。4.1 登錄功能Session 管理與密碼校驗登錄是入口邏輯不復雜但安全細節(jié)容易忽略。典型流程是JSP 表單提交賬號密碼 → Servlet 接收 → DAO 查庫比對 → 成功則寫 Session 并跳轉主頁。// LoginServlet.java 核心邏輯 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username req.getParameter(username); String password req.getParameter(password); UserDao userDao new UserDao(); User user userDao.findByUsername(username); if (user null) { req.setAttribute(msg, 用戶不存在); req.getRequestDispatcher(login.jsp).forward(req, resp); return; } // 密碼建議存 MD5 或 BCrypt 哈希別存明文 String hashed MD5Util.encode(password); if (!hashed.equals(user.getPassword())) { req.setAttribute(msg, 密碼錯誤); req.getRequestDispatcher(login.jsp).forward(req, resp); return; } req.getSession().setAttribute(currentUser, user); resp.sendRedirect(main.jsp); }這段代碼里findByUsername返回 null 和密碼不匹配要分開提示方便調(diào)試但生產(chǎn)環(huán)境建議統(tǒng)一提示賬號或密碼錯誤防止枚舉攻擊。密碼用 MD5 加鹽或 BCrypt 哈希項目里如果存的是明文建議自己補一個哈希工具類。Session 里存 User 對象后續(xù)頁面用session.getAttribute(currentUser)取當前登錄人配合一個登錄攔截 Filter 防止未登錄直接訪問內(nèi)部頁面。4.2 存款與查詢事務邊界與金額精度存款操作表面是加錢實際涉及賬戶余額更新和交易流水插入兩步必須放在一個事務里。public boolean deposit(String cardNo, BigDecimal amount) { Connection conn null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 開啟事務 // 第一步更新余額 String sql1 UPDATE account SET balance balance ? WHERE card_no ?; PreparedStatement ps1 conn.prepareStatement(sql1); ps1.setBigDecimal(1, amount); ps1.setString(2, cardNo); ps1.executeUpdate(); // 第二步插入流水 String sql2 INSERT INTO transaction(card_no, type, amount, trade_time) VALUES(?,?,?,NOW()); PreparedStatement ps2 conn.prepareStatement(sql2); ps2.setString(1, cardNo); ps2.setString(2, 存款); ps2.setBigDecimal(3, amount); ps2.executeUpdate(); conn.commit(); // 兩步都成功才提交 return true; } catch (Exception e) { if (conn ! null) conn.rollback(); // 任一步失敗全回滾 e.printStackTrace(); return false; } finally { DBUtil.close(conn); } }金額參數(shù)用BigDecimal而不是double這是銀行系統(tǒng)的鐵律。setAutoCommit(false)開啟事務兩步 SQL 都執(zhí)行成功才commit任何一步拋異常就rollback保證不會出現(xiàn)錢加了但沒流水或有流水但錢沒加的單邊情況。查詢功能相對簡單按卡號或交易時間范圍查transaction表注意分頁數(shù)據(jù)量大了不分頁會拖垮頁面。4.3 轉賬與活期轉定期跨賬戶操作的一致性轉賬是這套系統(tǒng)里最考驗事務設計的模塊涉及兩個賬戶的余額變動。public boolean transfer(String fromCard, String toCard, BigDecimal amount) { Connection conn null; try { conn DBUtil.getConnection(); conn.setAutoCommit(false); // 檢查轉出賬戶余額是否充足加行鎖防止并發(fā) String checkSql SELECT balance FROM account WHERE card_no ? FOR UPDATE; PreparedStatement checkPs conn.prepareStatement(checkSql); checkPs.setString(1, fromCard); ResultSet rs checkPs.executeQuery(); if (!rs.next() || rs.getBigDecimal(balance).compareTo(amount) 0) { conn.rollback(); return false; } // 扣轉出方 String outSql UPDATE account SET balance balance - ? WHERE card_no ?; // 加轉入方 String inSql UPDATE account SET balance balance ? WHERE card_no ?; // 插兩條流水 // ... 執(zhí)行后 commit conn.commit(); return true; } catch (Exception e) { if (conn ! null) conn.rollback(); return false; } finally { DBUtil.close(conn); } }關鍵在SELECT ... FOR UPDATE它給轉出賬戶的行加了排他鎖防止兩個并發(fā)轉賬同時讀到相同余額導致超額轉出?;钇谵D定期的邏輯類似只是目標從另一個活期賬戶變成定期存款表扣活期余額、插定期記錄、更新賬戶類型同樣在一個事務里完成。定期存款的利率和到期日計算項目里一般是按固定利率和存期算比如三個月 1.35%、一年 1.75%到期日 存入日 存期。5. 避坑與排查啟動報錯、亂碼、事務失效的常見問題這套項目雖然經(jīng)過驗證但換臺機器、換個版本就可能出問題。下面是我實際拆包時遇到的幾類高頻故障。5.1 啟動報 ClassNotFoundException: com.mysql.jdbc.Driver現(xiàn)象Tomcat 啟動后訪問登錄頁提交表單報 500控制臺提示找不到 MySQL 驅動類。原因項目用的驅動類名和實際 MySQL 版本不匹配或者mysql-connector-java.jar沒放進WEB-INF/lib。解決MySQL 8.0 用com.mysql.cj.jdbc.Driver5.7 用com.mysql.jdbc.Driver。確認 jar 包在WEB-INF/lib下IDEA 里還要在 Project Structure → Artifacts 里確認該 jar 被包含進輸出。改完重新 Build。5.2 頁面中文亂碼現(xiàn)象JSP 頁面顯示的問號或亂碼表單提交的中文存進數(shù)據(jù)庫變成亂碼。原因三處編碼沒統(tǒng)一——JSP 頁面pageEncoding、請求體編碼、數(shù)據(jù)庫連接串編碼。解決JSP 頭部加% page contentTypetext/html;charsetUTF-8 pageEncodingUTF-8 %Servlet 里req.setCharacterEncoding(UTF-8)和resp.setContentType(text/html;charsetUTF-8)連接串加characterEncodingutf8數(shù)據(jù)庫和表用utf8mb4。四處都對了才不會亂碼。5.3 轉賬后余額不對或流水缺失現(xiàn)象轉賬成功提示了但一方余額沒變或者流水少了一條。原因事務沒生效通常是setAutoCommit(false)沒設或者 DAO 里每次操作都拿了新連接導致兩步不在同一個事務里。解決確保整個轉賬流程共用一個 Connection在 Service 層開啟和提交事務DAO 層只負責執(zhí)行 SQL 不自己關連接。檢查conn.commit()和conn.rollback()是否成對出現(xiàn)。5.4 Tomcat 啟動端口被占用現(xiàn)象啟動報Address already in use: bind。原因8080 端口被其他程序另一個 Tomcat、某些開發(fā)工具占了。解決改 Tomcat 的conf/server.xml里 Connector 的 port或者用netstat -ano | findstr 8080找到占用進程結束掉。IDEA 里也可以在 Run Configuration 的 Startup/Connection 里改端口。5.5 靜態(tài)資源 404頁面沒樣式現(xiàn)象登錄頁能打開但沒樣式?jīng)]圖標控制臺一堆 404。原因CSS、JS、字體文件的路徑不對或者 Artifact 里沒包含 WebContent 下的靜態(tài)資源。解決檢查 JSP 里引用路徑是相對路徑還是絕對路徑建議用${pageContext.request.contextPath}/css/xxx.css。確認 Artifacts 的 Output Layout 里 WebContent 整個目錄被加進去了。字體文件那個_v4.3.0后綴如果沒去掉CSS 里引用的路徑對不上也會 404。6. 二次開發(fā)與驗證把課程設計改成能寫進簡歷的項目這套源碼直接交作業(yè)沒問題但如果你想讓它成為簡歷上的亮點得做點二次開發(fā)。我的習慣是先從數(shù)據(jù)庫設計文檔反推業(yè)務邊界再挑一兩個模塊做增強最后用測試用例驗證改動沒破壞原有功能。6.1 從功能驗證到自動化測試項目自帶的測試是手工點頁面報告里也是手工測試記錄。想驗證改動是否安全可以補幾個 JUnit 測試覆蓋核心邏輯Test public void testTransferInsufficientBalance() { AccountService service new AccountService(); // 轉出賬戶余額 100轉 200 應失敗 boolean result service.transfer(6222001, 6222002, new BigDecimal(200)); assertFalse(余額不足時應轉賬失敗, result); // 驗證雙方余額未變 assertEquals(new BigDecimal(100), service.getBalance(6222001)); } Test public void testDepositThenQuery() { AccountService service new AccountService(); service.deposit(6222001, new BigDecimal(500)); assertEquals(new BigDecimal(600), service.getBalance(6222001)); }這兩個用例一個測邊界余額不足一個測正常流程存款后查詢。跑通它們至少說明事務和金額計算沒大問題。測試數(shù)據(jù)用獨立的測試庫別污染演示數(shù)據(jù)。6.2 三個能寫進簡歷的增強方向第一加密碼加密和登錄攔截。把明文密碼改成 BCrypt 哈希加一個 Filter 攔截未登錄請求這是安全基線面試官看到會加分。第二加交易流水分頁和條件查詢。原項目的日志查看如果是一次性全查出來數(shù)據(jù)一多就卡。改成按時間范圍 交易類型 分頁查詢用LIMIT offset, size實現(xiàn)前端配合分頁組件。第三加簡單的并發(fā)控制演示。用 JMeter 或自己寫多線程模擬同一賬戶并發(fā)轉賬對比加FOR UPDATE和不加的結果這個實驗能讓你真正理解數(shù)據(jù)庫鎖面試時講出來很有說服力。6.3 驗證清單與交付前檢查改完之后按這個清單過一遍再交付檢查項驗證方法通過標準登錄正確/錯誤密碼各試一次正確進主頁錯誤有提示存款存 100 后查余額余額增加 100流水多一條轉賬轉出轉入各查一次雙方余額正確兩條流水定期活期轉定期后查兩張表活期減少定期增加并發(fā)兩線程同時轉同一賬戶無超額轉出余額正確亂碼輸入中文姓名和備注頁面和數(shù)據(jù)庫都正常顯示這套流程走下來你對 MVC 分層、事務管理、數(shù)據(jù)庫鎖的理解會比只跑通 demo 深一個層次。從那以后我每次拿到這類課程設計源碼都強制先跑一遍上面的驗證清單再動手改避免在錯誤的基礎上疊功能。希望這套拆解能幫你少走點彎路順利把項目跑起來、改下去。本文還有配套的精品資源點擊獲取