Microsoft Access (`.mdb` / `.accdb`) 作為輕量級桌面數據庫,常用於中小型項目、原遷移維護或嵌入式場景。Java 連接 Access 歷經兩代主流方案:
| 方案 | 原理 | 優點 | 缺點 | 適用版本 |
|---|---|---|---|---|
JDBC-ODBC Bridge (sun.jdbc.odbc.JdbcOdbcDriver) | JDBC -> ODBC 驅動 -> Access | JDK 內置,無需額外 JAR (JDK 7 及之前) | JDK 8 移除;需系統配置 ODBC 數據源 (DSN);32/64 位匹配麻煩;性能差;不支援 `.accdb` | JDK 7 及以下,舊系統維護 |
| UCanAccess (純 Java JDBC 驅動) | 基於 Jackcess 直接讀寫 Access 文件 | 無需 ODBC/DSN 配置;跨平台 (Win/Linux/Mac);支援 `.mdb`/`.accdb`;JDK 8/11/17+ 完美支援;Maven 中央倉庫易引入 | 需引入多個依賴 JAR (UCanAccess, Jackcess, HSQLDB, Commons Lang/Logging) | 現代首選方案 |
<dependency>
<groupId>net.sf.ucanaccess</groupId>
<artifactId>ucanaccess</artifactId>
<version>5.0.2</version> <!-- 檢查中央倉庫最新版 -->
</dependency>
會自動傳遞依賴:`jackcess`, `hsqldb`, `commons-lang3`, `commons-logging`。
<%@ page import="java.sql.*, javax.sql.*" %>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%
// 1. 數據庫文件路徑 (建議放在 WEB-INF 外或配置絕對路徑)
String dbPath = application.getRealPath("/WEB-INF/db/UserDatabase.accdb");
// 或絕對路徑: "D:/Data/UserDatabase.accdb"
// 2. UCanAccess 連接 URL 格式
// jdbc:ucanaccess://<文件路徑>[;參數]
String url = "jdbc:ucanaccess://" + dbPath;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 3. 獲取連接 (無需 Class.forName,JDBC 4.0 SPI 自動加載)
conn = DriverManager.getConnection(url);
// 4. 查詢示例
String sql = "SELECT UserName, PassWord FROM UserInformation";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
out.println("<table border='1'><tr><th>用戶名</th><th>密碼</th></tr>");
while (rs.next()) {
String user = rs.getString("UserName");
String pwd = rs.getString("PassWord");
out.println("<tr><td>" + user + "</td><td>" + pwd + "</td></tr>");
}
out.println("</table>");
} catch (SQLException e) {
e.printStackTrace();
out.println("數據庫錯誤: " + e.getMessage());
} finally {
// 5. 關鍵:標準關閉資源順序
try { if (rs != null) rs.close(); } catch (SQLException ignore) {}
try { if (pstmt != null) pstmt.close(); } catch (SQLException ignore) {}
try { if (conn != null) conn.close(); } catch (SQLException ignore) {}
}
%>
// 單獨打開 (排他鎖,防止其他進程寫入)
jdbc:ucanaccess://D:/db/test.accdb;singleConnection=true
// 內存模式 (讀取到內存,關閉時可選擇不寫回,適合只讀高併發)
jdbc:ucanaccess://D:/db/test.accdb;memory=true
// 指定編碼 (舊 .mdb 可能需要)
jdbc:ucanaccess://D:/db/test.mdb;charset=GBK
前置條件:Windows 系統、安裝 Access 或 Access Database Engine (ACE/OLEDB)、配置系統 DSN (控制面板 -> 管理工具 -> ODBC 數據源)。
<%@ page import="java.sql.*" %>
<%
// 1. 系統 DSN 名稱 (需在 ODBC 管理員預先創建,指向 .mdb 文件)
String dsn = "MyAccessDSN";
String url = "jdbc:odbc:" + dsn; // 無需文件路徑,DSN 內已配置
// 2. 載入橋接驅動 (JDK 內置 rt.jar)
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(url);
// 後續操作同標準 JDBC...
%>
致命缺陷:JDK 8+ **完全移除** `sun.jdbc.odbc` 包,代碼將拋出 `ClassNotFoundException`。切勿在新項目使用。
Access 定位是**單用戶桌面工具**,非多用戶服務端。Web 應用一旦超出極低併發、數據量小、純內網演示,請盡早遷移:
連接 Access,**請直接使用 UCanAccess**,拒絕 JDBC-ODBC Bridge。核心代碼即標準 JDBC,唯一差異在連接 URL (`jdbc:ucanaccess://...`)。但請清醒認識 Access 的**並發瓶頸、文件鎖風險、無事務隔離級別**,將其視為**過渡/演示/極小規模**方案,規劃遷移路徑才是長久之計。
]]>