首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 連接 Access 資料庫兩大方案:JDBC-ODBC 橋接與 UCanAccess 純 Java 驅動

     編輯:Java 相關知識

方案對比總覽

方案原理優點缺點現狀
JDBC-ODBC BridgeJDK 內建橋接器 → Windows ODBC 驅動 → Access無需額外 JAR、JDK 7 內建需機器配置 DSN、僅 Windows、32/64 位匹配問題、JDK 8 移除已廢棄 (JDK 8 移除)
UCanAccess純 Java 驅動 (基於 Jackcess/HSQLDB)跨平台、無需 ODBC/Access 安裝、支援 .mdb/.accdb、Maven 管理效能較原生略低、大檔案記憶體佔用高推薦方案 (活躍維護)
Jackcess底層純 Java Access 檔案讀寫庫無 JDBC 開銷、直接操作檔案非標準 JDBC API、功能較少底層庫,UCanAccess 依賴它

方案一:UCanAccess(現代標準做法)

Maven 依賴

<dependency>
    <groupId>net.sf.ucanaccess</groupId>
    <artifactId>ucanaccess</artifactId>
    <version>5.0.1</version> <!-- 檢查最新版 -->
</dependency>

傳遞依賴包含:jackcess、hsqldb、commons-lang3、commons-logging。

連接代碼範例

import java.sql.*;

public class UCanAccessDemo {
    public static void main(String[] args) {
        // 檔案路徑:.mdb (Access 2003) 或 .accdb (Access 2007+)
        String filePath = "C:/data/mydb.accdb";
        String url = "jdbc:ucanaccess://" + filePath; // 絕對路徑

        // 相對路徑(相對於 working directory)
        // String url = "jdbc:ucanaccess://./data/mydb.accdb";

        // 僅讀模式(避免鎖定檔案)
        // String url = "jdbc:ucanaccess://" + filePath + ";readonly=true";

        try (Connection conn = DriverManager.getConnection(url)) {
            System.out.println("連線成功!");

            // 查詢範例
            String sql = "SELECT id, name, email FROM users WHERE active = true";
            try (Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(sql)) {
                while (rs.next()) {
                    System.out.printf("ID:%d, Name:%s, Email:%s%n",
                        rs.getInt("id"), rs.getString("name"), rs.getString("email"));
                }
            }

            // 參數化查詢(防注入)
            String paramSql = "SELECT * FROM orders WHERE customer_id = ? AND order_date > ?";
            try (PreparedStatement ps = conn.prepareStatement(paramSql)) {
                ps.setInt(1, 1001);
                ps.setDate(2, java.sql.Date.valueOf("2024-01-01"));
                try (ResultSet rs = ps.executeQuery()) {
                    // 處理結果
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

方案二:JDBC-ODBC(僅限 JDK 7 及以下歷史系統)

// 僅供參考,現代專案勿使用
String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/data/mydb.mdb";
// 或使用系統 DSN
// String url = "jdbc:odbc:MyAccessDSN";

try {
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // JDK 內建
    Connection conn = DriverManager.getConnection(url, "username", "password");
    // ...
} catch (Exception e) {
    e.printStackTrace();
}

進階配置與優化

1. 連線池整合

// HikariCP 配置範例
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:ucanaccess://C:/data/mydb.accdb");
config.setDriverClassName("net.ucanaccess.jdbc.UcanaccessDriver");
config.setMaximumPoolSize(5); // Access 並發能力有限,建議小池
config.setConnectionTimeout(30000);
HikariDataSource ds = new HikariDataSource(config);

2. 大檔案效能優化

  • jdbc:ucanaccess://path?memory=false:關閉記憶體資料庫鎮像,直接讀寫檔案(減少記憶體,降低速度)。
  • jdbc:ucanaccess://path?opencursor=true:保持游標開啟,適合大量讀取。
  • 定期 CHECKPOINT 或 BACKUP 壓縮資料庫檔案。

3. 常見錯誤排查

錯誤原因解決
No suitable driver驅動類未載入、Maven 依賴缺失檢查 ucanaccess JAR、DriverManager.getConnection 自動載入 (JDBC 4.0+)
File locked / Permission deniedAccess 檔案被其他程式獨佔、唯讀屬性關閉 Access 應用程式、檔案屬性移除唯讀、或用 readonly=true
OutOfMemoryError大資料庫載入記憶體加 memory=false、增加 JVM -Xmx、分批處理
Unsupported operationAccess SQL 語法差異使用 Access 相容 SQL、避免複雜 JOIN/子查詢

遷移建議:從 Access 走向標準關聯式資料庫

Access 適合單機小型應用,企業級系統建議遷移至:

  • 嵌入式:H2、Derby、SQLite(無伺服器、純 Java/JDBC)
  • 客戶端-伺服器:MySQL、PostgreSQL、MariaDB(免費開源、高併發)
  • 企業級:Oracle、SQL Server、DB2

遷移策略:UCanAccess 導出 SQL → 目標資料庫匯入 → 修正語法差異 → 切換連線池配置。

總結

  • JDBC-ODBC 已死 (JDK 8 移除),歷史專案升級 JDK 時必須遷移。
  • UCanAccess 是現代標準:跨平台、Maven 管理、純 Java、支援 .mdb/.accdb。
  • 生產環境注意:Access 並發寫入弱、檔案鎖定易衝突、大檔案效能差,核心業務請遷移標準 RDBMS。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved