杰瑞科技汇

java访问access数据库

核心概念

Java本身并不直接提供访问Access数据库的驱动程序,我们需要借助一个第三方库,这个库就是 UCanAccess,它是一个纯Java实现的Jet/ACE引擎驱动,允许我们通过JDBC来连接和操作Access数据库。


第一步:环境准备

  1. 安装Microsoft Access 你需要一个Access数据库文件(.accdb.mdb),如果你没有,可以创建一个,我们以 .accdb 为例。

  2. 准备数据库文件

    • 创建一个Access数据库,例如命名为 mydb.accdb
    • 在其中创建一张表,Students
    • Students 表添加一些字段,如 ID (自动编号/主键), Name (文本), Age (数字), EnrollmentDate (日期/时间)。
    • 插入几条测试数据。

    Students表示例: | ID | Name | Age | EnrollmentDate | |----|------|-----|----------------| | 1 | 张三 | 20 | 2025-09-01 | | 2 | 李四 | 21 | 2025-09-02 | | 3 | 王五 | 22 | 2025-09-03 |

  3. 下载UCanAccess库 你需要从UCanAccess的官方网站下载最新的jar包,推荐下载 Bundle 版本,因为它包含了所有必需的依赖项。

    • 下载地址: https://sourceforge.net/projects/ucanaccess/
    • 下载后,你会得到一个zip文件,解压后你会看到很多 .jar 文件,其中最重要的是:
      • ucanaccess-x.x.x.jar (核心库)
      • 其他依赖库,如 jackcess-x.x.x.jar, commons-lang-x.x.jar 等,如果你下载的是Bundle版本,这些都在里面。
  4. 配置Java项目 将下载到的所有 .jar 文件添加到你的Java项目的类路径中。

    • 在IDE中 (如 IntelliJ IDEA 或 Eclipse):
      • 右键你的项目 -> Build Path / Project Structure -> Libraries。
      • 点击 "Add External JARs..." 或类似按钮,然后选择所有你从UCanAccess zip包中解压出来的 .jar 文件。
    • 在命令行中:
      • 编译时: javac -cp "path/to/all/jar_files/*" YourProgram.java
      • 运行时: java -cp "path/to/all/jar_files/*;." YourProgram
      • 注意: Windows系统使用分号 分隔路径,Linux/macOS使用冒号 。

第二步:编写Java代码

下面是一个完整的、分步的Java代码示例,展示了如何连接、查询、插入、更新和删除数据。

加载驱动并建立连接

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class AccessDBConnection {
    // 数据库连接URL
    // 格式: jdbc:ucanaccess://<数据库文件的绝对路径>
    private static final String DB_URL = "jdbc:ucanaccess://C:/path/to/your/database/mydb.accdb";
    public static void main(String[] args) {
        Connection conn = null;
        try {
            // 1. 加载驱动 (UCanAccess 4.0.0+ 版本后,此步骤可选,但推荐保留)
            Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
            // 2. 建立连接
            System.out.println("正在连接到Access数据库...");
            conn = DriverManager.getConnection(DB_URL);
            System.out.println("数据库连接成功!");
            // 在这里执行其他数据库操作...
            //  AccessDBExample.performOperations(conn);
        } catch (ClassNotFoundException e) {
            System.err.println("找不到UCanAccess驱动类: " + e.getMessage());
        } catch (SQLException e) {
            System.err.println("数据库连接或操作出错: " + e.getMessage());
        } finally {
            // 3. 关闭连接
            if (conn != null) {
                try {
                    conn.close();
                    System.out.println("数据库连接已关闭。");
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

完整的CRUD操作示例

这是一个更完整的类,展示了如何执行增、删、改、查操作。

import java.sql.*;
public class AccessDBExample {
    // 数据库连接URL (请务必修改为你的数据库文件路径)
    private static final String DB_URL = "jdbc:ucanaccess://C:/path/to/your/database/mydb.accdb";
    public static void main(String[] args) {
        Connection conn = null;
        try {
            // 1. 连接数据库
            conn = DriverManager.getConnection(DB_URL);
            System.out.println("连接成功!");
            // 2. 执行查询操作
            queryStudents(conn);
            // 3. 执行插入操作
            // insertStudent(conn, "赵六", 23);
            // 4. 执行更新操作
            // updateStudentAge(conn, 1, 25);
            // 5. 执行删除操作
            // deleteStudent(conn, 3);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 查询所有学生
    private static void queryStudents(Connection conn) throws SQLException {
        String sql = "SELECT ID, Name, Age, EnrollmentDate FROM Students";
        Statement stmt = null;
        ResultSet rs = null;
        try {
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            System.out.println("\n--- 学生列表 ---");
            while (rs.next()) {
                // 通过列名获取数据,可读性更好,且不受列顺序影响
                int id = rs.getInt("ID");
                String name = rs.getString("Name");
                int age = rs.getInt("Age");
                Date date = rs.getDate("EnrollmentDate");
                System.out.println("ID: " + id + ", 姓名: " + name + ", 年龄: " + age + ", 入学日期: " + date);
            }
        } finally {
            // 关闭资源,遵循后开先关的原则
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
        }
    }
    // 插入一个新学生
    private static void insertStudent(Connection conn, String name, int age) throws SQLException {
        // 使用PreparedStatement可以防止SQL注入,并且更高效
        String sql = "INSERT INTO Students (Name, Age) VALUES (?, ?)";
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, name);
            pstmt.setInt(2, age);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("\n插入操作成功,影响了 " + affectedRows + " 行。");
        } finally {
            if (pstmt != null) pstmt.close();
        }
    }
    // 更新学生年龄
    private static void updateStudentAge(Connection conn, int id, int newAge) throws SQLException {
        String sql = "UPDATE Students SET Age = ? WHERE ID = ?";
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, newAge);
            pstmt.setInt(2, id);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("\n更新操作成功,影响了 " + affectedRows + " 行。");
        } finally {
            if (pstmt != null) pstmt.close();
        }
    }
    // 删除学生
    private static void deleteStudent(Connection conn, int id) throws SQLException {
        String sql = "DELETE FROM Students WHERE ID = ?";
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, id);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("\n删除操作成功,影响了 " + affectedRows + " 行。");
        } finally {
            if (pstmt != null) pstmt.close();
        }
    }
}

第三步:常见问题与解决方案

  1. 问题: net.ucanaccess.jdbc.UcanaccessDriver - Class not found

    • 原因: UCanAccess的jar包没有正确添加到项目的Classpath中。
    • 解决: 仔细检查IDE的库配置或命令行的-cp参数,确保包含了所有必要的jar文件。
  2. 问题: Database <path> not foundThe database file cannot be found

    • 原因: JDBC URL中的数据库文件路径不正确。
    • 解决:
      • 强烈建议使用绝对路径C:/Users/YourUser/Documents/mydb.accdb
      • 确保路径中的分隔符是正确的(Windows用\,但在Java字符串中最好用或双反斜杠\\)。
      • 确保文件确实存在于该位置。
  3. 问题: Database is exclusively locked by another user or process

    • 原因: 这是最常见的问题之一。
      • Access数据库文件被另一个程序(如Microsoft Access本身、另一个Java程序)打开了。
      • 数据库文件没有正确关闭。
    • 解决:
      • 确保没有任何其他程序正在打开.accdb文件,关闭所有Microsoft Access窗口。
      • 如果是Java程序自身的问题,确保Connection对象在finally块中被正确关闭。
      • 如果问题依旧,可以尝试在JDBC URL中添加属性来处理锁定问题,
        String DB_URL = "jdbc:ucanaccess://C:/path/to/your/database/mydb.accdb;lockfile=true";
        // 或者
        String DB_URL = "jdbc:ucanaccess://C:/path/to/your/database/mydb.accdb;ignoreCase=true";
  4. 问题: Could not initialize class net.ucanaccess.jdbc.UcanaccessDriver

    • 原因: 通常是依赖库缺失或版本不兼容。
    • 解决: 确保你已经将UCanAccess Bundle包中的所有jar文件都添加到了Classpath中,而不仅仅是ucanaccess.jar
  5. 问题: 日期/时间处理问题

    • 原因: Access和Java的日期类型不完全对应。
    • 解决: UCanAccess提供了java.sql.Timestampjava.util.Date的良好支持,如果遇到问题,可以尝试在URL中添加属性:
      String DB_URL = "jdbc:ucanaccess://...;dateFormats=yyyy-MM-dd;timeFormats=HH:mm:ss";

在Java中访问Access数据库的步骤可以总结为:

  1. 准备环境: 创建Access数据库并下载UCanAccess库。
  2. 配置项目: 将UCanAccess的所有JAR文件添加到项目的Classpath。
  3. 编写代码:
    • 使用 jdbc:ucanaccess://<path_to_db> 作为连接URL。
    • 使用 DriverManager.getConnection() 获取连接。
    • 使用 StatementPreparedStatement 执行SQL语句。
    • 使用 ResultSet 读取查询结果。
    • 务必在finally块中关闭Connection, Statement, ResultSet,以释放资源。
    • 处理可能发生的 SQLException
  4. 调试: 遇到问题时,首先检查路径、锁定问题和Classpath配置。

希望这份详细的指南能帮助你成功地在Java项目中集成Access数据库!

分享:
扫描分享到社交APP
上一篇
下一篇