雖然 Access 已非主流生產資料庫,但在輕量級桌面應用、遷移專案、單元測試替身中仍常見。JDBC 連接 Access 主要有三條路徑,本文詳細對比優劣、提供可直接複製的連線代碼,並解決「找不到資料源」、「架構不匹配 (32/64 位)」等經典坑。
已廢棄:JDK 8 起移除 sun.jdbc.odbc.JdbcOdbcDriver。若維護極舊系統 (JDK 7-):
MyAccessDSN,選擇 .mdb/.accdb 檔案。Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection("jdbc:odbc:MyAccessDSN", "", "");
⚠ 致命缺陷:效能差、非跨平台、JDK 8+ 無法使用、需管理員配置 DSN、部署麻煩。
在連線字串內直接指定驅動與檔案路徑,無需建立系統 DSN,部署極簡:
// .mdb (Access 2003-)
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/data/test.mdb";
// .accdb (Access 2007+)
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/data/test.accdb";
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn = DriverManager.getConnection(url, "", ""); // Access 預設無密碼或僅資料庫密碼
關鍵點:
DBQ 使用正斜線 或雙反斜線 C:\\data\\test.mdb。;PWD=your_password。JdbcOdbcDriver 僅 32 位。64 位 JDK 無法載入。解決:安裝 32 位 JDK/JRE 運行應用,或升級方案三。現代標準解法:UCanAccess 基於 Jackcess 實現純 Java 讀寫 Access,無需 ODBC、無需 Access 安裝、支援 .mdb/.accdb、Maven 中央倉庫可用。
<dependency>
<groupId>net.sf.ucanaccess</groupId>
<artifactId>ucanaccess</artifactId>
<version>5.0.1</version> <!-- 檢查最新版 -->
</dependency>
傳遞依賴:jackcess, commons-lang3, commons-logging, hsqldb (內嵌用於複雜查詢)。
// .accdb
String url = "jdbc:ucanaccess://C:/data/test.accdb";
// .mdb
String url = "jdbc:ucanaccess://C:/data/test.mdb";
// 可選參數
// 單獨連線 (預設共享 hsqldb 快取)
String url = "jdbc:ucanaccess://C:/data/test.accdb;singleConnection=true";
// 忽略大小寫
String url = "jdbc:ucanaccess://C:/data/test.accdb;ignoreCase=true";
// 記憶體模式 (唯讀、極快)
String url = "jdbc:ucanaccess://C:/data/test.accdb?memory=true";
Connection conn = DriverManager.getConnection(url); // 自動載入驅動 (JDBC 4.0+)
try (Connection conn = DriverManager.getConnection("jdbc:ucanaccess://C:/data/test.accdb");
Statement stmt = conn.createStatement()) {
// 建表
stmt.execute("CREATE TABLE users (id COUNTER PRIMARY KEY, name TEXT(50), age INT)");
// 插入
try (PreparedStatement ps = conn.prepareStatement("INSERT INTO users(name, age) VALUES(?, ?)")) {
ps.setString(1, "Alice");
ps.setInt(2, 25);
ps.executeUpdate();
}
// 查詢
try (ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) {
System.out.printf("ID:%d Name:%s Age:%d%n",
rs.getInt("id"), rs.getString("name"), rs.getInt("age"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
| 維度 | 方案一: 系統 DSN | 方案二: 免 DSN ODBC | 方案三: UCanAccess |
|---|---|---|---|
| JDK 版本 | ≤ 7 | ≤ 7 | 8 - 21+ |
| 平台 | 僅 Windows | 僅 Windows | 跨平台 (Win/Linux/Mac) |
| 架構 | 32 位限制 | 32 位限制 | 32/64 位通用 |
| 部署 | 需配置 DSN | 僅需檔案路徑 | 僅需 JAR 包 |
| 效能 | 低 | 低 | 中 (純 Java、Jackcess 優化) |
| 功能支援 | 完整 | 完整 | 大多數 SQL、部分複雜查詢轉 hsqldb |
| 維護狀態 | 已移除 | 已移除 | 活躍維護 |
No suitable driver found for jdbc:ucanaccess://...DriverManager.getConnection 觸發 SPI 載入。java.lang.UnsatisfiedLinkError (方案二)conn.setAutoCommit(false) + 批次 executeBatch() + 定期 commit()。JDK 8+ 環境下,**UCanAccess 是連接 Access 的唯一正解**:純 Java、跨平台、無配置、Maven 化。方案一、二僅供維護 JDK 7 以下遺留系統參考。長遠規劃應將 Access 視為「遷移來源」而非「運行時依賴」,盡早導出資料至標準關係型資料庫。