ODBC 資料源資訊儲存在 Windows 登錄檔中,路徑通常為:
HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\<資料源名稱>
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\<資料源名稱>
Java 本身無原生 API 操作登錄檔,需透過 JNI 呼叫 Windows API 或使用第三方庫(如 com.ice.jni.registry、ca.beq.util.win32.registry、jna)實現。
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegStringValue;
public class CreateOdbcDsn {
public static void main(String[] args) {
String dsnName = "DBF_DataSource";
String dbfDir = "F:/data/dbf/";
String driver = "Microsoft dBase Driver (*.dbf)";
try {
// 1. 開啟/建立 ODBC.INI 節點
RegistryKey odbcIni = Registry.HKEY_CURRENT_USER
.openSubKey("Software")
.openSubKey("ODBC")
.openSubKey("ODBC.INI");
// 若不存在則建立
if (odbcIni == null) {
odbcIni = Registry.HKEY_CURRENT_USER
.createSubKey("Software\\ODBC\\ODBC.INI");
}
// 2. 建立/開啟特定 DSN 節點
RegistryKey dsnKey = odbcIni.createSubKey(dsnName);
// 3. 寫入核心屬性
dsnKey.setValue(new RegStringValue("Driver", driver));
dsnKey.setValue(new RegStringValue("DefaultDir", dbfDir));
dsnKey.setValue(new RegStringValue("Database", dbfDir));
dsnKey.setValue(new RegStringValue("DriverId", "277"));
dsnKey.setValue(new RegStringValue("FIL", "dBase IV"));
dsnKey.setValue(new RegStringValue("MaxBufferSize", "2048"));
dsnKey.setValue(new RegStringValue("PageTimeout", "600"));
// 4. 同時註冊到 ODBC Data Sources 列表
RegistryKey dsnList = odbcIni.openSubKey("ODBC Data Sources");
if (dsnList == null) dsnList = odbcIni.createSubKey("ODBC Data Sources");
dsnList.setValue(new RegStringValue(dsnName, driver));
System.out.println("ODBC DSN [" + dsnName] + " 建立成功!");
} catch (Exception e) {
System.err.println("建立 DSN 失敗: " + e.getMessage());
e.printStackTrace();
}
}
}
| 屬性名 | 用途 | 範例值 |
|---|---|---|
| Driver | ODBC 驅動程式描述名稱(需與系統安裝的驅動完全一致) | Microsoft dBase Driver (*.dbf) |
| DefaultDir | DBF 檔案所在目錄(必須以斜線結尾) | F:/data/dbf/ |
| Database | 同 DefaultDir,部分驅動需同時設定 | F:/data/dbf/ |
| FIL | 檔案格式版本 | dBase IV / dBase 5.0 |
| DriverId | 驅動程式 ID | 277 (dBase) |
操作登錄檔存在平台鎖定、權限、JNI 部署複雜等問題。現代專案建議採用純 Java 方案:
<dependency>
<groupId>com.healthmarketscience.jackcess</groupId>
<artifactId>jackcess</artifactId>
<version>4.0.4</version>
</dependency>
// 直接讀取 DBF,無需 ODBC
Table table = new DBFReader(new File("data.dbf")).getTable();
for (Row row : table) {
System.out.println(row.get("FIELD_NAME"));
}
針對簡單 DBF 結構,可自行實作 DBF 標頭解析 + 記錄讀取,零依賴。
Java 8 起移除 sun.jdbc.odbc.JdbcOdbcDriver,Java 7 亦不建議使用。請勿在新專案採用「建立 DSN → JDBC-ODBC Bridge 連線」架構。
雖可透過 JNI 操作登錄檔動態建立 ODBC DSN,但此技術棧屬舊世代方案,存在平台鎖定、部署複雜、維護困難等缺點。新專案強烈建議採用 Jackcess、XBaseJ 等純 Java 庫直接讀寫 DBF,或將 DBF 轉換為 SQLite/CSV 等現代格式後再處理。若受限於既有系統必須使用 ODBC,請將 DSN 建立邏輯封裝為安裝腳本(PowerShell/NSIS/Inno Setup)而非 Java 運行時動態建立,降低運行時風險。