
簡介JSP連接ACCESS數據庫是Web開發(fā)中一種基礎的數據交互方式常用于小型項目與課堂實驗。教程面向Java Web初學者幫助讀者快速掌握通過JDBC-ODBC橋驅動訪問Access數據庫的完整流程也適合需要完成課程設計的在校學生。內容以一個可運行的示例展開先建立包含uid和pwd文本字段的數據庫再將數據庫文件放入Tomcat的指定data目錄接著編寫JSP頁面完成連接、查詢和結果展示涵蓋從數據庫準備到頁面輸出的完整鏈路。文檔不僅完整給出可直接運行的代碼還逐段解釋連接字符串構造、物理路徑轉換、驅動加載、資源關閉等關鍵環(huán)節(jié)并提示最常見的數據庫連接錯誤及排錯思路方便讀者對照排查。同時指出Access更適合學習實踐若遷移到MySQL等企業(yè)級數據庫需更換驅動和連接方式有助于建立更系統(tǒng)的JDBC認知。壓縮包內僅含1個doc格式文檔大小約31KB內容高度濃縮示例代碼可直接復制使用。目前已有240人學習下載值得正在自學JSP與數據庫交互的讀者參考。1. JSP 連接 ACCESS 數據庫一份最輕量的 JDBC-ODBC 橋接樣例JSP 連接 ACCESS 數據庫聽起來像十年前的產物但在今天的小型管理系統(tǒng)、課堂演示和內部表單場景里它依然是最省事的方案。Access 把數據直接存在一個 .mdb 文件里不需要單獨安裝數據庫服務JSP 頁面通過 JDBC-ODBC 橋讀取文件內容整個項目里只有數據庫文件和 JSP 兩樣東西。這份資源要做的事很明確創(chuàng)建 test.mdb里面建一張 username 表存 uid、pwd 兩個文本字段把數據庫文件放進 Tomcat 的 webapps\ROOT\data 目錄再寫一個 JDBCAccess.jsp負責加載驅動、建立連接、執(zhí)行 select 查詢并把結果輸出到瀏覽器。適合剛接觸 Web 開發(fā)的初學者也適合需要在內網機器上快速復現老項目的開發(fā)者跑通它等于把 JDBC 和 JSP 內置對象里最常用的一段流程完整走了一遍。2. 環(huán)境準備Access 建庫、JDK 版本與 Tomcat 目錄三件事這套代碼能跑起來一半靠 JSP 代碼一半靠運行環(huán)境。我見過不少人把代碼原樣粘進新項目結果驅動加載就拋異常。問題不在代碼而在 JDK 版本、Access 驅動位數、數據庫文件存放位置這三件事沒對上。這一章先把環(huán)境鋪好再進入代碼拆解。2.1 技術底座JDBC-ODBC 橋的老原理與新限制JDBC-ODBC 橋的定位是讓 Java 程序通過 JDBC API 訪問任何帶有 ODBC 驅動的關系型數據庫。sun.jdbc.odbc.JdbcOdbcDriver 這個類把 JDBC 方法調用轉換成 ODBC 調用再由 ODBC 層加載 Microsoft Access Driver (*.mdb) 去讀寫文件。整個過程里沒有獨立的數據庫服務進程數據文件本身被當作數據庫來處理。對 Access 這種輕量文件庫來說這個機制幾乎是零成本接入。這套橋接機制在 JDK 7 及以前一直是 JDK 自帶的功能Class.forName(sun.jdbc.odbc.JdbcOdbcDriver) 可以直接加載成功。JDK 8 開始官方移除了這個橋接類理由是長期無人維護且官方建議改用廠商提供的原生驅動。因此想原樣跑通這份樣例最省事的是使用 JDK 6 或 JDK 7 配合對應版本的 Tomcat。JSP 頁面里用到的語法都極其基礎不依賴任何新版本特性舊環(huán)境反而更合適。先說一個實踐中的認知誤區(qū)不是“代碼寫對了就能連上”。Class.forName 只在 JDK 的類庫里能找到這個類時才成功。機子上裝的是 JDK 8第一行連接就會拋 ClassNotFoundException。這也是很多人在新環(huán)境復現老項目時遇到的第一個坎。所以拿到這份資源先別急著貼代碼打開命令行執(zhí)行 java -version看版本號是不是 8 以下。還有一點值得說明為什么不直接用 MySQL 或 PostgreSQL因為這份樣例所在的場景里往往沒有數據庫管理員權限或者目標機器上根本沒裝數據庫服務。Access 文件即庫拷走一個 .mdb 文件就等于遷移了整個庫這種便攜性在演示、教學和單機內部工具里非常實用。它不適合做高并發(fā)在線業(yè)務這是后續(xù)二次開發(fā)時要有預期的地方。2.2 建庫建表test.mdb 與 username 表怎么生成創(chuàng)建數據庫文件建議用 Access 桌面版直接操作。如果沒有安裝完整 Office也可以裝 Access Runtime 環(huán)境用空庫入口創(chuàng)建文件。最終需要的產物只有一個test.mdb 內部有一張 username 表表里包含 uid 和 pwd 兩個文本字段。這一步直接在 Access 的查詢設計視圖里執(zhí)行一句建表 SQL 就能完成。CREATE TABLE username ( uid TEXT(50), pwd TEXT(50) );這段 SQL 建的表沒有主鍵學習階段足夠用。字段大小寫成 TEXT(50)是因為代碼里的 rs.getString(uid) 本來就是按字符串讀取50 的容量存放普通用戶名和密碼不會超長。生產級設計里通常還會給 uid 加唯一約束但本題場景保持原樣更貼近樣例本身。有一點需要提醒Access 的 SQL 方言和 MySQL 有不小差別它不支持在同一個建表語句里寫 IF NOT EXISTS。重復執(zhí)行上面的 SQL 會提示“數據庫中已存在同名對象”。因此建表前先確認庫是新創(chuàng)建的或者手動刪掉舊表再重新建。建完表之后順手往表里插入兩條數據讓 JSP 查詢時有內容可顯示。這步同樣在 Access 查詢視圖中執(zhí)行。INSERT INTO username (uid, pwd) VALUES (admin, 123456); INSERT INTO username (uid, pwd) VALUES (guest, guest);插入完成后可以打開表確認數據存在然后保存文件。注意保存時不要勾選需要登錄才能打開庫的選項否則 JSP 連接時會被攔在數據庫認證這一步。2.3 數據庫放哪getRealPath 的路徑映射機制數據庫文件做出來之后第二個關鍵步驟是放對位置。按這份樣例的約定test.mdb 放在 Tomcat 的 webapps\ROOT\data 目錄下。這里要特別注意ROOT 不是磁盤根目錄而是 Tomcat 中默認 Web 應用上下文對應的目錄也就是打開 http://localhost:8080 時訪問的那個應用根目錄。代碼里使用 application.getRealPath(spath) 來獲取物理路徑。application 是 JSP 內置的 ServletContext 對象getRealPath 接收一個相對于當前 Web 應用根目錄的虛擬路徑返回對應的磁盤絕對路徑。舉個例子Tomcat 安裝在 C 盤默認目錄那么 getRealPath(data/test.mdb) 一般會得到類似 C:\Tomcat\webapps\ROOT\data\test.mdb 的結果。這個機制的價值在于你不需要在代碼里寫死機器路徑部署到任何目錄都能自動推導出數據庫的真實位置。很多初學者習慣直接寫 D:\test.mdb 這種絕對路徑結果換一臺機器就報文件找不到。改用 getRealPath 之后只要 .mdb 文件在 JSP 所在的同一個應用目錄里路徑推導就永遠正確。這也解釋了為什么必須在 ROOT 下建 data 目錄——因為 JSP 部署在 ROOT 里相對路徑以 ROOT 為基準。整個應用目錄的最終形態(tài)如下webapps └── ROOT ├── JDBCAccess.jsp └── data └── test.mdb這里有一個 Windows 下容易被忽略的細節(jié)如果 Tomcat 被安裝到 Program Files 這類需要管理員權限的目錄下JSP 讀取數據庫一般沒問題但后續(xù)要執(zhí)行 insert 時可能會因為寫權限不足而報“文件共享鎖定數不夠”。遇到時優(yōu)先把 Tomcat 換到純英文且無空格、無系統(tǒng)保護的目錄里能省下不少折騰時間。3. 核心代碼逐段拆解一個 JSP 頁面走完連接到輸出的完整鏈路樣例里最核心的就是 JDBCAccess.jsp。它把完整鏈路切成四段加載驅動、建立連接、執(zhí)行查詢、輸出結果。每一段都有對應代碼下面把每一段的含義和參數說明展開講。3.1 連接段url 拼裝、驅動加載與建立連接整個 JSP 的入口先聲明頁面類型和導入 Java SQL 包然后是連接代碼。下面是最核心的連接片段。try { String spath data/test.mdb; // 相對 Web 應用根目錄的路徑 String dbpath application.getRealPath(spath); // 將相對路徑轉成磁盤絕對路徑 String url jdbc:odbc:Driver{Microsoft Access Driver (*.mdb)};DBQ dbpath; Class.forName(sun.jdbc.odbc.JdbcOdbcDriver); // 加載 JDBC-ODBC 橋驅動 Connection conn DriverManager.getConnection(url); // 建立數據庫連接第一行的 spath 是相對于應用根目錄的路徑正斜杠在 Windows 下同樣兼容。第三行把數據源名 dbname、用戶名 user、密碼 password 都留成空字符串因為 Access 文件型數據庫默認不需要賬號體系。真正的連接字符串由固定前綴和動態(tài) DBQ 參數拼接而成。url 的值最終類似于 jdbc:odbc:Driver{Microsoft Access Driver (*.mdb)};DBQC:\Tomcat\webapps\ROOT\data\test.mdb。這里的每一段都不能寫錯。Driver 后面的花括號是 ODBC 驅動名的一部分刪掉花括號 ODBC 管理器就識別不了驅動DBQ 是 Database Qualified 的縮寫后面直接跟數據庫文件的物理路徑分號是參數分隔符路徑里如果出現分號或者特殊字符就會引發(fā)解析問題。url 拼好后Class.forName 觸發(fā)驅動的靜態(tài)注冊邏輯把 JdbcOdbcDriver 注冊到 DriverManager 的驅動列表里隨后 DriverManager.getConnection(url) 根據 url 前綴找到 ODBC 橋驅動完成連接。很多人在這一步容易踩到幾個理解偏差。一是認為 Class.forName 返回的對象需要用變量接住其實這一步只為了觸發(fā)類加載和注冊返回值完全可以忽略。二是認為 DriverManager.getConnection 必須傳用戶名密碼實際 Access 場景里直接傳一個 url 參數就夠了用戶名密碼留空即可。三是認為 url 里的 DBQ 可以寫相對路徑不行ODBC 驅動只認磁盤絕對路徑這也是前面必須用 getRealPath 的原因。3.2 查詢段Statement 的滾動參數與 ResultSet 取值連接建立后就是執(zhí)行 SQL 查詢并讀取結果集。這一段是整份樣例的輸出核心。Statement stmt conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rs stmt.executeQuery(select * from username); while (rs.next()) { out.print(用戶名: rs.getString(uid)); out.print( 密碼: rs.getString(pwd) br); } out.print(br恭喜你數據庫連接成功);conn.createStatement 接收兩個常量參數ResultSet.TYPE_SCROLL_SENSITIVE 表示結果集可以雙向滾動并且能感知到其他連接的更新ResultSet.CONCUR_UPDATABLE 表示允許通過結果集直接更新數據庫。對于學習這個樣例而言這兩個參數可以用默認的 createStatement() 簡寫替代效果一致。這里特意寫成完整參數是想展示 JDBC 結果集控制的完整能力。executeQuery 執(zhí)行 select 語句并返回 ResultSet 對象。rs.next() 的作用是讓游標向后移動一行返回 true 時表示當前行有數據返回 false 表示結果集已經讀完。rs.getString(uid) 按列名從當前行取出 uid 字段的值也可以按列索引寫成 rs.getString(1)。頁面上的 out.print 是 JSP 內置對象 response 的簡化輸出方式最終輸出到瀏覽器響應體里。這里有一個初學者很容易誤會的現象如果 username 表是空表while 循環(huán)一次都不會進入頁面只會顯示最后的“恭喜你”一行。新手往往以為代碼沒生效實際上是因為表里沒有數據。所以建庫時往里插入兩行測試數據頁面一打開就能看到明確效果。關于關閉順序代碼里先 rs.close()再 stmt.close()最后 conn.close()三個關閉操作嚴格遵循由內到外的順序。ResultSet 是建立在 Statement 之上的Statement 又依賴于 Connection反向關閉會導致底層資源釋放不完整在高頻訪問時容易把數據庫連接耗盡。雖然 JSP 頁面結束時會自動清理本次請求的資源但養(yǎng)成手動關閉的習慣在寫真正業(yè)務代碼時非常重要。3.3 輸出與異常錯誤信息如何暴露在頁面上整段代碼被一個 try-catch 包裹一旦任意一個環(huán)節(jié)出現異常catch 塊會把異常信息輸出到頁面上。} catch (Exception e) { out.print(數據庫連接錯誤,錯誤信息如下br); out.print(e.getMessage()); }catch 塊里調用 e.getMessage() 而不是 e.printStackTrace()這是一個面向頁面調試的取舍。getMessage() 返回的是異常的一句話描述適合直接顯示給瀏覽器printStackTrace() 會把完整堆棧打到 Tomcat 控制臺信息更全但對頁面調試不友好。建議排查時兩者配合先用 getMessage() 看清楚錯誤類型再翻控制臺看具體棧幀。頁面頂部的 contentTypetext/html; charsetgb2312 和 meta 標簽聲明了輸出編碼。gb2312 對簡體中文夠用但現代 Tomcat 默認以 UTF-8 解析 JSP 文件如果文件保存編碼和頁面聲明不一致就會出現中文亂碼。這個問題會在后面的避坑章節(jié)專門展開。4. 避坑指南驅動消失、路徑空格、亂碼和文件鎖的排查經驗下面把這份樣例最常見的問題按“現象 → 原因 → 解決”逐條整理。這些都是實際部署時反復出現的照著排查能省下大半天的定位時間?,F象一頁面報 ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver。原因是 JDK 8 及以上已經移除了 JDBC-ODBC 橋驅動類不存在于類庫中Tomcat 運行時使用的是高版本 JDKClass.forName 自然找不到。解決方法是安裝 JDK 7 并把 Tomcat 的 JAVA_HOME 變量指向它保持原代碼不修改如果必須用新 JDK可以改用 UCanAccess 這類純 Java 驅動把連接字符串換成 jdbc:access:// 協議但這就偏離了樣例本身的橋接方式?,F象二驅動加載成功但連接失敗提示“未發(fā)現數據源名稱并且未指定默認驅動程序”。常見原因是 64 位系統(tǒng)下的 ODBC 驅動與 JDK 位數不匹配32 位 JDK 找不到 64 位的 Access 驅動還有一種可能是機器上安裝的 Access 驅動顯示名不是花括號里的寫法。解決方法是打開 ODBC 數據源管理器32 位系統(tǒng)運行 odbcad32.exe64 位系統(tǒng)要區(qū)分 SysWOW64 下的版本在“驅動程序”選項卡里核對驅動顯示名并安裝與 JDK 位數一致的 Microsoft Access Database Engine。現象三頁面提示找不到文件或路徑錯誤但 data 目錄和 test.mdb 確實存在。最常見的原因是 Tomcat 安裝路徑帶有空格比如 Windows 默認的 Program Files 目錄DBQ 參數拼接后無法正確解析。解決方法是把 Tomcat 挪到純英文且無空格的目錄如 D:\Tomcat或者臨時在代碼里輸出 dbpath 變量確認 getRealPath 到底解析到了哪個物理路徑。注意絕對路徑方案雖然能繞過 getRealPath 的問題但換機器后必須改代碼只適合應急。現象四頁面中文全部變成問號或亂碼。原因是 JSP 文件聲明的是 gb2312但文件實際以 UTF-8 保存Tomcat 解析 JSP 時按文件原始編碼讀取字符流最終與頁面聲明的輸出編碼不一致。解決方法是把頁面的 contentType 和 meta 標簽統(tǒng)一改成 UTF-8同時確保 JSP 文件用 UTF-8 編碼保存。數據庫里已經存在的亂碼數據需要重新錄入不是改頁面編碼就能恢復的?,F象五能連接成功但執(zhí)行 insert 時報“文件共享鎖定數不夠”或“數據庫被鎖定”。原因是 Access 文件鎖機制要求同一時刻只能有一個進程以讀寫方式打開數據庫Tomcat 進程和本機手工打開的 Access 客戶端之間發(fā)生競爭殘留的 .ldb 鎖文件也會導致異常。解決方法是排查是否有人用 Access 打開了 test.mdb關閉所有外部進程刪除 data 目錄下的 .ldb 文件再給目錄授權寫權限。修改數據庫結構時先停 Tomcat 再操作改完再啟動是比較穩(wěn)妥的流程。5. 運行驗證部署進 Tomcat 后如何確認真正讀到了庫代碼和環(huán)境都準備好之后剩下的問題就是怎么把項目跑起來并且在出錯時定位到具體環(huán)節(jié)。這一章給出完整的部署路徑和驗收方法。5.1 目錄復制與啟動順序部署前先確認最終目錄結構只包含兩個必要文件。以 Tomcat 6.0 為例把 JDBCAccess.jsp 復制到 webapps\ROOT 目錄下把 test.mdb 復制到 webapps\ROOT\data 目錄下。如果 ROOT 下還沒有 data 目錄手動新建一個Tomcat 不會自動創(chuàng)建它。目錄確認無誤后進入 Tomcat 的 bin 目錄雙擊 startup.batWindows或執(zhí)行 ./startup.shLinux??吹娇刂婆_輸出類似“Server startup in xxx ms”的信息后打開瀏覽器訪問 http://localhost:8080/JDBCAccess.jsp。如果 8080 端口被占用需要先修改 conf\server.xml 里的 Connector port再重啟 Tomcat。這里有一個部署路徑的細節(jié)如果不想把文件放在 ROOT 里也可以在 webapps 下新建一個名為 app 的目錄把 JSP 和 data 目錄都放進去然后訪問 http://localhost:8080/app/JDBCAccess.jsp。這種情況下 application.getRealPath 的相對基準會跟著應用上下文變化getRealPath(data/test.mdb) 會解析到 webapps\app\data\test.mdb不需要改代碼。這也體現了 getRealPath 相對路徑設計的好處應用目錄遷移不會破壞路徑映射。5.2 頁面結果與錯誤信息對照正常情況下頁面會依次輸出 username 表里的所有記錄最后一行是“恭喜你數據庫連接成功”。如果數據庫里插入了前面準備的兩條測試數據頁面應該顯示用戶名:admin 密碼:123456 用戶名:guest 密碼:guest 恭喜你數據庫連接成功如果頁面出現異常信息先別急著改代碼對照異常內容判斷屬于哪一層。下面這張表是實際運行中最常出現的錯誤信息與處理方向錯誤信息片段問題層處理方向ClassNotFoundException: JdbcOdbcDriverJDK 層換回 JDK 7或改用第三方 Access 驅動未發(fā)現數據源名稱并且未指定默認驅動程序ODBC 層核對驅動顯示名匹配 JDK 位數文件名或路徑錯誤 / 數據庫名被截斷路徑層檢查 DBQ 路徑移除空格和中文java.io.FileNotFoundException路徑層檢查 data 目錄與 test.mdb 文件名是否完全一致文件共享鎖定數不夠文件鎖層關閉外部 Access 進程刪除 .ldb 文件5.3 用 dbpath 做現場診斷頁面報錯但看不清是路徑問題還是驅動問題時可以直接在代碼里臨時加一行輸出。out.print(DBPath dbpath br);這行放在 url 拼裝之前刷新頁面就能看到 JSP 實際解析到的磁盤絕對路徑。把這個路徑復制到資源管理器里檢查能立刻確認文件是否真的存在于該目錄、文件名大小寫是否一致、路徑中是否包含空格或中文。確認完之后把這一行刪掉避免正式頁面暴露服務器路徑。這個診斷手段也適合排查“代碼在別人電腦上能跑在我這里不行”的問題。大部分情況下最終都會落在 dbpath 解析結果和本機 Access 驅動位數這兩個變量上。把輸出結果對比一下問題往往馬上定位。6. 二次開發(fā)把只讀樣例改成能登錄、能寫入的工具6.1 從查詢改成登錄校驗最常見的改造方向是把頁面變成登錄頁。在 JSP 里接收表單提交的 uid 和 pwd拼到查詢條件里有結果就提示登錄成功沒有結果就提示失敗。String uid request.getParameter(uid); String pwd request.getParameter(pwd); String sql select * from username where uid uid and pwd pwd ;這個寫法能快速演示業(yè)務邏輯但存在 SQL 拼接注入風險。做二次開發(fā)時第一件事應該把 Statement 換成 PreparedStatement用占位符傳參。6.2 把連接代碼抽成公共方法每個 JSP 都重復寫一遍 Class.forName 和 DriverManager.getConnection代碼會越來越臃腫。常見做法是寫一個 db.Conn 工具類把驅動加載和連接創(chuàng)建都封裝進去頁面里只調用一句話。連接參數放到一個配置變量里統(tǒng)一管理后續(xù)換數據庫或調整路徑只需要改一處。6.3 擴展成增刪改把 executeQuery 換成 executeUpdate就能執(zhí)行 insert、update、delete 語句。Access 的 SQL 語法與標準 SQL 基本一致插入數據用 INSERT INTO 表名 (字段) VALUES (值)。需要注意 Access 的并發(fā)能力弱這個方案更適合后臺管理和教學演示不要把它推到高并發(fā)的線上業(yè)務里。我在剛學 JSP 時也是從這份橋接代碼起步的。那之后每次在陌生機器上跑老項目我都會先敲一遍 java -version 確認 JDK 版本再從 ODBC 管理器核對驅動位數最后才動代碼。這套習慣幫我避開了無數次驅動消失和路徑解析的坑。希望幫到你。本文還有配套的精品資源點擊獲取