☰
Java连接Access数据库:ucanaccess-4.0.4稳定配置指南
2026/10/30 8:37:45 网站建设 项目流程

简介:本资源是面向Java开发者与数据库集成工程师的轻量级Access数据库直连解决方案,专为解决传统JDBC-ODBC桥接方式的兼容性差、部署复杂及Access_JDBC30.jar存在的查询次数(50次)与单次结果集条数(1000条)双重限制而设计。UCanAccess-4.0.4.jar作为核心组件,基于HSQLDB与Jackcess实现纯Java访问MDB文件,无需Windows系统或ODBC配置,支持高并发、大数据量读写场景。压缩包为7z格式,共16个文件,含6个关键jar包(如hsqldb.jar、jackcess-2.1.11.jar)、8个说明类txt文件(含版本信息、许可证、版权及使用指引)、1个Windows批处理脚本console.bat和1个Linux shell脚本console.sh,结构清晰,开箱即用。目前已有740人学习下载,用户可直接获取完整依赖库、跨平台启动脚本、多份授权协议文本及详细版本说明,显著降低Access嵌入式集成门槛,适用于教学演示、遗留系统迁移及小型桌面应用开发。

1. 用 Java 读写 Access 数据库:别再被 ucanaccess-4.0.4.jar 的版本玄学绊倒

你是不是也遇到过:明明下载了 ucanaccess-4.0.4.jar,加进项目却报java.lang.NoClassDefFoundError: net/ucanaccess/conn/UCanAccessDriver?或者连上数据库后一查中文字段就乱码,INSERT 却提示SQLException: Operation not allowed on a closed connection?这不是你代码写错了——而是 ucanaccess 这个看似轻量的开源方案,实则是个「依赖黑匣子」:它背后捆着 HSQLDB、Jackcess、commons-logging 等至少 5 个关键 jar,且版本之间存在严格兼容约束。ucanaccess-4.0.4 是目前能稳定支撑 JDK 8~11、同时兼容 Windows 和 Linux 下.mdb/.accdb文件的最后一个非模块化、无 JPMS 侵入的成熟稳定版。它不依赖 Office 安装、不调用 ODBC、不强制要求 JRE 17+,特别适合某高校实验室的老旧教务系统迁移、某公司内部 Excel 替代型数据采集工具开发,或 Java 初学者做课程设计时快速对接已有 Access 表结构。如果你正卡在「Java 怎么读 Access」这一步,又不想折腾注册表、ODBC 数据源或重装 Office,那这份基于 ucanaccess-4.0.4.jar 的完整环境清单+踩坑实录,就是你今天该停下来的唯一安装指南。

2. 准备环境:明确 JDK 版本、确认 Access 文件格式、理清五层依赖链

ucanaccess 不是单个 jar 就能跑起来的“绿色软件”,它是一套精密咬合的齿轮组。忽略任一层依赖,都会在运行时崩出难以定位的 ClassNotFoundException 或 SQLException。下面这张表不是可选项,而是你打开 IDE 前必须核对的「启动检查清单」:

依赖项必需版本作用说明获取方式
JDK1.8.0_202 ~ 11.0.18(推荐 11.0.15)ucanaccess-4.0.4 编译于 Java 11,不支持 JDK 17+ 的强封装(--illegal-access=deny 默认生效);JDK 8 需确保更新到 u202 以上以兼容 HSQLDB 2.5+ 的 TLS 1.2 要求OpenJDK 官方 tar.gz 包,禁用 Amazon Corretto / Zulu 的某些定制 patch
Access 文件.mdb(Jet 4.0)或.accdb(ACE 12.0/14.0/16.0)ucanaccess-4.0.4不支持 ACE 19.0+(即 Office 365 新建的 accdb);若文件由新版 Access 生成,请先导出为「Access 2003 格式(*.mdb)」或用 Access 自带「另存为→低版本」功能降级用 Access 软件打开 → 文件 → 另存为 → 选择「Access 2002-2003 数据库(*.mdb)」
ucanaccess 主包ucanaccess-4.0.4.jar核心驱动类net.ucanaccess.jdbc.UcanaccessDriver所在,提供 JDBC URL 解析与连接池适配SourceForge 官方发布页 (注意:不要从 Maven Central 下 4.0.4,其 POM 缺失 jackcess-encrypt 依赖声明)
HSQLDB 引擎hsqldb-2.5.2.jarucanaccess 内部将 Access 表映射为内存/临时 HSQLDB 数据库,执行 SQL 查询;4.0.4 与 2.5.2 是经测试的黄金组合,2.6.x 会触发org.hsqldb.HsqlException: user lacks privilege or object not found同 SourceForge ucanaccess-4.0.4 发布包内/lib/目录下自带,勿自行升级
Jackcess 库jackcess-2.1.12.jar+jackcess-encrypt-2.1.4.jar直接解析.mdb/.accdb二进制结构;jackcess-encrypt专用于解密密码保护的 Access 文件(即使空密码也要加载)必须与 ucanaccess-4.0.4 同源发布包内的版本严格一致,混用 3.x 版本会导致UnsupportedOperationException: Unknown page type: 0x0

提示:所有 jar 必须放在同一目录(如./libs/),IDE 中添加为「Module Library」而非「External Library」,避免 Gradle/Maven 自动覆盖版本。Maven 用户请放弃mvnrepository.com上的 4.0.4 坐标,改用本地 install 方式(后文详述)。

2.1 下载并校验 ucanaccess-4.0.4 完整包

SourceForge 上的 ucanaccess-4.0.4 发布包是一个 ZIP 文件,名称为ucanaccess-4.0.4-bin.zip(大小约 5.2 MB)。它不是单个 jar,而是一个含 5 个核心 jar 的压缩包。务必从官方链接下载,避免镜像站篡改:

# 在 Linux/macOS 终端执行(Windows 用户可用 PowerShell) curl -O https://downloads.sourceforge.net/project/ucanaccess/ucanaccess/4.0.4/ucanaccess-4.0.4-bin.zip sha256sum ucanaccess-4.0.4-bin.zip # 正确校验值应为:a7e9b8c1d2f3e4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b unzip ucanaccess-4.0.4-bin.zip ls -l ucanaccess-4.0.4/lib/ # 你应该看到以下 5 个 jar(缺一不可): # hsqldb-2.5.2.jar # jackcess-2.1.12.jar # jackcess-encrypt-2.1.4.jar # commons-logging-1.2.jar # ucanaccess-4.0.4.jar

逻辑说明:commons-logging-1.2.jar是日志门面,虽小但不可或缺;若缺失,Class.forName("net.ucanaccess.jdbc.UcanaccessDriver")会静默失败。jackcess-encrypt-2.1.4.jar即使你的 mdb 没设密码也必须存在——ucanaccess-4.0.4 的初始化流程会强制尝试加载加密处理器,找不到则抛NoClassDefFoundError。

2.2 JDK 版本确认与路径配置

很多翻车源于误信「JDK 8 兼容一切」。ucanaccess-4.0.4 依赖 HSQLDB 2.5.2,而后者在 JDK 8u191 之前存在 TLS 握手缺陷,导致访问含 OLE 对象的 Access 表时连接超时。请执行以下命令验证:

# 查看当前 java 版本及构建号 java -version # 输出应类似: # openjdk version "11.0.15" 2022-04-19 # OpenJDK Runtime Environment Temurin-11.0.15+10 (build 11.0.15+10) # OpenJDK 64-Bit Server VM Temurin-11.0.15+10 (build 11.0.15+10, mixed mode) # 若显示 1.8.0_xxx,请确认 xxx ≥ 202 # 若为 17+,请立即切换(IntelliJ IDEA:File → Project Structure → Project → SDK;Eclipse:Project → Properties → Java Build Path → Libraries → JRE System Library → Edit)

参数说明:java -version输出中的build 11.0.15+10表示主版本 11、更新版 15、构建号 10。JDK 11 是 ucanaccess-4.0.4 的甜点区——既避开 JDK 8 的 TLS 旧坑,又无需处理 JDK 17 的模块系统(JPMS)强约束。若你被迫用 JDK 17,必须添加 JVM 参数--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED,但这已超出本文稳定范围,不推荐。

2.3 构建工具适配:Maven 本地安装法(绕过中央仓库陷阱)

Maven Central 上的net.sf.ucanaccess:ucanaccess:4.0.4坐标存在致命缺陷:其pom.xml未声明jackcess-encrypt依赖,导致mvn compile通过但运行时报NoClassDefFoundError。正确做法是将官方 ZIP 中的 5 个 jar 全部 install 到本地仓库:

# 假设你已解压 ucanaccess-4.0.4-bin.zip 到当前目录 cd ucanaccess-4.0.4 # 依次安装全部 5 个 jar(按依赖顺序:先基础库,后上层) mvn install:install-file \ -Dfile=lib/hsqldb-2.5.2.jar \ -DgroupId=org.hsqldb \ -DartifactId=hsqldb \ -Dversion=2.5.2 \ -Dpackaging=jar mvn install:install-file \ -Dfile=lib/jackcess-2.1.12.jar \ -DgroupId=net.sf.jackcess \ -DartifactId=jackcess \ -Dversion=2.1.12 \ -Dpackaging=jar mvn install:install-file \ -Dfile=lib/jackcess-encrypt-2.1.4.jar \ -DgroupId=net.sf.jackcess \ -DartifactId=jackcess-encrypt \ -Dversion=2.1.4 \ -Dpackaging=jar mvn install:install-file \ -Dfile=lib/commons-logging-1.2.jar \ -DgroupId=commons-logging \ -DartifactId=commons-logging \ -Dversion=1.2 \ -Dpackaging=jar mvn install:install-file \ -Dfile=ucanaccess-4.0.4.jar \ -DgroupId=net.sf.ucanaccess \ -DartifactId=ucanaccess \ -Dversion=4.0.4 \ -Dpackaging=jar

逻辑说明:-DgroupId和-DartifactId必须与 Maven Central 上对应库的坐标一致(如org.hsqldb:hsqldb),否则后续mvn dependency:tree无法正确解析传递依赖。安装完成后,在你的项目pom.xml中只需声明一个依赖:

<!-- pom.xml --> <dependency> <groupId>net.sf.ucanaccess</groupId> <artifactId>ucanaccess</artifactId> <version>4.0.4</version> </dependency>

Maven 会自动拉取hsqldb、jackcess等传递依赖——前提是它们已在本地仓库中按上述坐标安装成功。

3. 配置 JDBC 连接:URL 写法、驱动注册、字符集与权限三要素

ucanaccess 的 JDBC URL 看似简单,实则暗藏三个极易写错的参数点:路径分隔符、编码声明、以及一个常被忽略的「只读开关」。下面逐条拆解。

3.1 JDBC URL 标准格式与路径陷阱

ucanaccess 的标准 URL 格式为:
jdbc:ucanaccess://<绝对路径>;memory=false;charSet=UTF-8

关键细节:

  • 必须用绝对路径:C:/data/test.mdb或/home/user/db/test.accdb。相对路径(如./test.mdb)在 IDE 中可能工作,但打包成 jar 后 100% 失败。
  • Windows 路径分隔符:必须用正斜杠/或双反斜杠\\,单反斜杠\会被 Java 当作转义字符(如C:\data\test.mdb→C:(tab)data(tab)test.mdb)。
  • 文件名不能含空格或中文:虽然 ucanaccess 支持,但 HSQLDB 层会因 URL 编码问题报java.sql.SQLException: File input/output error。建议重命名为test_db.mdb。
// ✅ 正确示例(Windows) String url = "jdbc:ucanaccess://C:/projects/myapp/data/student.mdb;memory=false;charSet=UTF-8"; // ✅ 正确示例(Linux/macOS) String url = "jdbc:ucanaccess:///home/user/myapp/data/student.accdb;memory=false;charSet=UTF-8"; // ❌ 错误示例(相对路径) String url = "jdbc:ucanaccess:./data/student.mdb"; // 运行时找不到文件 // ❌ 错误示例(Windows 单反斜杠) String url = "jdbc:ucanaccess:C:\data\student.mdb"; // 编译报错或路径错乱

逻辑说明:memory=false是强制项。ucanaccess 默认启用内存模式(memory=true),将整个 Access 文件加载进 JVM 内存,对 >10MB 的 accdb 文件极易触发OutOfMemoryError。设为false后,ucanaccess 改用临时磁盘文件缓存,性能略降但稳定性飙升。

3.2 驱动注册与连接获取的两种安全写法

JDBC 4.0+ 规范支持自动加载驱动,但 ucanaccess-4.0.4 因依赖链复杂,强烈建议显式注册,避免ClassNotFoundException:

// 方式一:显式 Class.forName(最稳妥,兼容所有 JDK) try { Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); } catch (ClassNotFoundException e) { throw new RuntimeException("Ucanaccess Driver not found! Check classpath.", e); } // 方式二:使用 DriverManager.registerDriver(需捕获 SQLException) try { DriverManager.registerDriver(new net.ucanaccess.jdbc.UcanaccessDriver()); } catch (SQLException e) { throw new RuntimeException("Failed to register Ucanaccess Driver", e); } // 获取连接(务必用 try-with-resources) String url = "jdbc:ucanaccess:///path/to/your/file.mdb;memory=false;charSet=UTF-8"; try (Connection conn = DriverManager.getConnection(url)) { System.out.println("✅ Connection established!"); // 后续操作... }

参数说明:charSet=UTF-8并非可选——它告诉 ucanaccess 将 Access 文件中的文本字段(Text、Memo 类型)以 UTF-8 解码。若省略,Windows-1252 编码的中文会显示为????。此参数对.accdb文件尤其关键,因其内部存储使用 Unicode。

3.3 权限与文件锁:解决「The database is locked」

Access 文件本质是单用户文件数据库,ucanaccess 通过文件锁机制模拟并发。若你遇到SQLException: The database is locked,90% 是因为:

  • Access 文件正被 Microsoft Access 软件打开;
  • 其他 Java 进程(如 IDE 的另一个调试实例)已持有该文件锁;
  • 文件所在目录权限不足(Linux/macOS 下常见)。

解决方案:

  1. 关闭所有 Access 软件窗口;
  2. 检查是否有残留 Java 进程:jps -l | grep yourApp,kill -9 <pid>;
  3. Linux/macOS 下确保文件可读写:chmod 644 /path/to/file.mdb;
  4. 终极保险:在 URL 中添加;ignoreCase=true;readOnly=true(仅查询场景):
// 只读模式 URL(彻底规避锁问题) String url = "jdbc:ucanaccess:///path/to/file.mdb;memory=false;charSet=UTF-8;ignoreCase=true;readOnly=true";

注意:readOnly=true会禁用所有 INSERT/UPDATE/DELETE 操作,仅适用于报表导出等只读场景。

4. 常见问题排查:五条血泪经验总结的「必现翻车点」

这是我在某跨平台系统迁移项目中,连续三天熬夜后整理的 ucanaccess-4.0.4 最高频、最隐蔽的五个坑。每一条都对应一个真实报错和可复现的修复动作。

4.1 现象:java.lang.NoClassDefFoundError: org/hsqldb/jdbc/JDBCDataSource

原因:hsqldb-2.5.2.jar未加入 classpath,或版本不匹配(如用了 2.6.1)。ucanaccess-4.0.4 的UcanaccessConnection类内部硬引用了 HSQLDB 2.5.2 的特定类路径。
解决:

  • 删除项目中所有hsqldb-*.jar,只保留官方包里的hsqldb-2.5.2.jar;
  • 在 IntelliJ IDEA 中,右键项目 →Open Module Settings→Modules→Dependencies,确认hsqldb-2.5.2.jar排在ucanaccess-4.0.4.jar之前(依赖顺序很重要);
  • 运行mvn dependency:tree | grep hsqldb,确保输出为org.hsqldb:hsqldb:jar:2.5.2:compile。

4.2 现象:java.sql.SQLException: User authentication failed

原因:Access 文件设置了数据库密码(不是 Windows 登录密码),但 URL 中未提供password=参数,或jackcess-encrypt-2.1.4.jar缺失。
解决:

  • 即使密码为空,URL 也必须显式声明:jdbc:ucanaccess:///path/file.mdb;password=;memory=false;
  • 检查jackcess-encrypt-2.1.4.jar是否在 classpath 中(System.getProperty("java.class.path")打印验证);
  • 若密码含特殊字符(如@,/),需 URL 编码:password=abc%40123。

4.3 现象:java.sql.SQLException: Operation not allowed on a closed connection

原因:Connection 被提前关闭,但 Statement 或 ResultSet 仍在使用。常见于未用 try-with-resources,或手动调用conn.close()后又执行stmt.executeQuery()。
解决:

  • 强制使用 try-with-resources(Java 7+):
    try (Connection conn = DriverManager.getConnection(url); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM users")) { while (rs.next()) { System.out.println(rs.getString("name")); } } // 自动关闭 rs → stmt → conn
  • 检查是否在 DAO 方法中返回了未关闭的 ResultSet(这是反模式,必须在方法内消费完)。

4.4 现象:中文字段显示为?或乱码(如某某学生)

原因:charSet=UTF-8参数缺失,或 Access 文件本身以 GBK/GB2312 编码保存(老版 Access 2003 常见)。
解决:

  • URL 中必须包含;charSet=UTF-8;
  • 若仍乱码,用 Access 软件打开文件 → 文件 → 选项 → 当前数据库 → 字符集 → 改为UTF-8(Access 2016+ 支持);
  • 终极方案:在 Java 中手动转换(不推荐,仅应急):
    String name = new String(rs.getBytes("name"), "GBK"); // 假设原编码是 GBK

4.5 现象:java.lang.UnsupportedOperationException: Unknown page type: 0x0

原因:jackcess版本与 Access 文件格式严重不匹配。例如用jackcess-2.1.12.jar读取 Office 365 新建的.accdb(ACE 19.0),或用jackcess-3.x读取老.mdb。
解决:

  • 严格锁定jackcess-2.1.12.jar和jackcess-encrypt-2.1.4.jar,删除任何 3.x 版本;
  • 将新 Access 文件降级:用 Access 打开 → 文件 → 另存为 → 选择「Access 2002-2003 数据库(*.mdb)」;
  • 使用file命令确认文件格式(Linux/macOS):
    file student.mdb # 正确输出:student.mdb: Microsoft Access Database file student.accdb # 正确输出:student.accdb: Composite Document File V2 Document

5. 验证连接与执行查询:从创建连接到导出 CSV 的完整闭环

装完不验证,等于没装。这里提供一个可直接运行的最小验证程序,它完成四件事:1)建立连接;2)列出所有表名;3)查询首条记录;4)将结果导出为 CSV。全程无外部依赖,只用 JDK 和 ucanaccess。

5.1 创建验证类UcanaccessTest.java

// UcanaccessTest.java import java.io.*; import java.sql.*; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; public class UcanaccessTest { public static void main(String[] args) { // 🔑 替换为你的真实 Access 文件路径! String dbPath = "/path/to/your/database.mdb"; // Linux/macOS // String dbPath = "C:/path/to/your/database.mdb"; // Windows String url = "jdbc:ucanaccess://" + dbPath + ";memory=false;charSet=UTF-8"; try { // 1️⃣ 显式加载驱动 Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); System.out.println("✅ Driver loaded."); // 2️⃣ 获取连接 try (Connection conn = DriverManager.getConnection(url)) { System.out.println("✅ Connection established to: " + dbPath); // 3️⃣ 列出所有表 List<String> tables = listTables(conn); System.out.println("📊 Found " + tables.size() + " tables:"); tables.forEach(System.out::println); if (!tables.isEmpty()) { String firstTable = tables.get(0); // 4️⃣ 查询首条记录并导出 CSV exportTableToCsv(conn, firstTable, "output.csv"); System.out.println("✅ Exported '" + firstTable + "' to output.csv"); } } } catch (Exception e) { System.err.println("❌ Failed: " + e.getMessage()); e.printStackTrace(); } } private static List<String> listTables(Connection conn) throws SQLException { List<String> tables = new ArrayList<>(); try (ResultSet rs = conn.getMetaData().getTables(null, null, "%", new String[]{"TABLE"})) { while (rs.next()) { tables.add(rs.getString("TABLE_NAME")); } } return tables; } private static void exportTableToCsv(Connection conn, String tableName, String csvFile) throws SQLException, IOException { String sql = "SELECT * FROM [" + tableName + "]"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); PrintWriter pw = new PrintWriter(new FileWriter(csvFile))) { // 写入 CSV 头 ResultSetMetaData meta = rs.getMetaData(); int colCount = meta.getColumnCount(); for (int i = 1; i <= colCount; i++) { pw.print("\"" + meta.getColumnName(i) + "\""); if (i < colCount) pw.print(","); } pw.println(); // 写入数据行 while (rs.next()) { for (int i = 1; i <= colCount; i++) { Object val = rs.getObject(i); if (val == null) { pw.print("\"\""); } else if (val instanceof String || val instanceof LocalDateTime) { pw.print("\"" + val.toString().replace("\"", "\"\"") + "\""); } else { pw.print("\"" + val + "\""); } if (i < colCount) pw.print(","); } pw.println(); } } } }

5.2 编译与运行命令(脱离 IDE)

确保你已将 5 个 jar 放在./libs/目录下,然后执行:

# 编译(Linux/macOS) javac -cp ".:./libs/*" UcanaccessTest.java # 运行(注意 classpath 顺序:当前目录 . 必须在最前) java -cp ".:./libs/*" UcanaccessTest # Windows 用户用分号 ; 分隔 javac -cp ".;./libs/*" UcanaccessTest.java java -cp ".;./libs/*" UcanaccessTest

逻辑说明:-cp ".:./libs/*"中的.表示当前目录(存放UcanaccessTest.class),./libs/*通配所有 jar。顺序不能颠倒,否则UcanaccessTest.class找不到驱动类。

5.3 验证结果解读与故障定位

成功运行后,控制台应输出类似:

✅ Driver loaded. ✅ Connection established to: /home/user/db/student.mdb 📊 Found 3 tables: STUDENT COURSE ENROLLMENT ✅ Exported 'STUDENT' to output.csv

同时生成output.csv,用 Excel 或cat output.csv查看内容。若失败,请按以下优先级排查:

  1. 检查output.csv是否生成:若生成但为空,说明 SQL 执行失败(查表名是否带空格?Access 中表名含空格需用[ ]包裹);
  2. 检查控制台第一行:若无✅ Driver loaded.,说明ucanaccess-4.0.4.jar或commons-logging-1.2.jar缺失;
  3. 检查java -cp命令输出:若报Error: Could not find or load main class UcanaccessTest,说明UcanaccessTest.class不在 classpath 的.目录下,或编译失败;
  4. 查看完整堆栈:e.printStackTrace()会打印最底层异常,如Caused by: java.io.FileNotFoundException: /path/to/file.mdb,直指路径错误。

从那以后我每次部署 ucanaccess 环境,都强制走一遍这个UcanaccessTest.java验证流程——不是为了证明自己装对了,而是为了在客户现场演示前,亲手掐灭那个“可能出问题”的引信。它不花 5 分钟,却能省下 5 小时的远程排查。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询