0Pricing
Java Academy · 课时

JDBC 基础

连接、语句与结果集

JDBC 基础 是 CoddyKit 上的免费 Java Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。

什么是 JDBC?

JDBC(Java 数据库连接)是从 Java 访问关系型数据库的标准应用程序接口。

  • 它位于 java.sql 包中。
  • 每种数据库都会提供一个实现 JDBC 接口的驱动程序。
  • 您应针对 Connection、Statement 和 ResultSet 等接口编写代码,而不是直接针对供应商类编写代码。

借助这一抽象,同一份代码就能用于 PostgreSQL、MySQL、H2 或 Oracle。

核心接口

三个接口承担了大部分工作:

  • Connection——与数据库建立的开放会话。
  • Statement / PreparedStatement——发送 SQL。
  • ResultSet——用于遍历查询返回行的游标。

您可以从 DriverManager 或 DataSource 获取 Connection。

打开连接

DriverManager.getConnection(url, user, password) 返回一个活动的 Connection。

JDBC 连接地址用于标识数据库,例如 jdbc:postgresql://localhost:5432/shop。现代驱动程序会自动注册自身,因此您不再需要调用 Class.forName(...)。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://localhost:5432/shop";
        try (Connection conn = DriverManager.getConnection(url, "app", "secret")) {
            System.out.println("Connected: " + !conn.isClosed());
        } catch (SQLException e) {
            System.out.println("Connection failed: " + e.getMessage());
        }
    }
}

资源自动管理

Connection、Statement 和 ResultSet 都实现了 AutoCloseable。

请始终将它们放在资源自动管理代码块中,这样即使抛出异常,它们也会自动关闭。连接泄漏会迅速耗尽数据库连接。

  • 资源会按照相反的顺序关闭。
  • 不需要 finally 代码块。

运行查询

对于简单的 SELECT,请创建一个 Statement 并调用 executeQuery,它会返回一个 ResultSet。

示例使用内存模拟,因此您无需连接真实数据库也能看到完整流程。在生产环境中,SQL 会针对该连接执行。

import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Simulated result of: SELECT name FROM users
        List<String> names = List.of("Ada", "Linus", "Grace");
        System.out.println("Query returned " + names.size() + " rows:");
        for (String name : names) {
            System.out.println(" - " + name);
        }
    }
}

读取 ResultSet

ResultSet 初始位置在第一行之前。请在循环中调用 rs.next();没有更多行时,它会返回 false。

您可以通过列名或从 1 开始的索引,使用类型化读取方法读取列:

  • rs.getInt("id")
  • rs.getString("name")
  • rs.getDouble("price")
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://localhost:5432/shop";
        try (Connection conn = DriverManager.getConnection(url, "app", "secret");
             Statement st = conn.createStatement();
             ResultSet rs = st.executeQuery("SELECT id, name FROM users")) {
            while (rs.next()) {
                System.out.println(rs.getInt("id") + ": " + rs.getString("name"));
            }
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

用于写入的 executeUpdate

对于 INSERT、UPDATE 和 DELETE,请使用 executeUpdate。它会返回一个 int,表示受影响的行数。

只有在您事先不知道语句是否会返回结果集时,才使用 execute。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:postgresql://localhost:5432/shop";
        try (Connection conn = DriverManager.getConnection(url, "app", "secret");
             Statement st = conn.createStatement()) {
            int rows = st.executeUpdate("DELETE FROM sessions WHERE expired = true");
            System.out.println("Deleted " + rows + " rows");
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

将行映射为对象

大多数应用程序都会将每一行转换为一个领域对象。请遍历 ResultSet 并构建对象实例。

下面是这种模式的示例,经过模拟后可以独立运行。使用 record 可以简洁地完成映射。

import java.util.ArrayList;
import java.util.List;

public class Main {
    record User(int id, String name) {}

    public static void main(String[] args) {
        // Stand-in for iterating a ResultSet
        String[][] rows = {{"1", "Ada"}, {"2", "Linus"}};
        List<User> users = new ArrayList<>();
        for (String[] row : rows) {
            users.add(new User(Integer.parseInt(row[0]), row[1]));
        }
        users.forEach(System.out::println);
    }
}

处理 SQLException

几乎所有 JDBC 方法都会抛出受检查异常 SQLException。

它包含有用的诊断信息:

  • getMessage()——面向用户的可读文本。
  • getSQLState()——标准的 5 个字符状态代码。
  • getErrorCode()——供应商特定的代码。

请记录这些信息,不要将异常吞掉。

import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        SQLException e = new SQLException("duplicate key", "23505", 7);
        System.out.println("Message: " + e.getMessage());
        System.out.println("SQLState: " + e.getSQLState());
        System.out.println("ErrorCode: " + e.getErrorCode());
    }
}

DatabaseMetaData

conn.getMetaData() 返回一个描述数据库本身的 DatabaseMetaData 对象。

它可以告诉您产品名称和版本、支持的功能,甚至列出表和列。这就是架构浏览器等工具无需硬编码供应商细节便能工作的方式。

整合起来

典型的读取流程如下:

  • 在资源自动管理代码块中打开 Connection。
  • 创建一个 Statement(或者更好的选择是 PreparedStatement)。
  • 调用 executeQuery,并使用 rs.next() 循环读取。
  • 将列映射到对象中。
  • 让资源自动管理机制关闭所有资源。

下一课将让查询能够抵御注入攻击。

快速检查

Statement.executeUpdate 会返回什么?

回顾

现在您已经了解 JDBC 的核心流程:

  • DriverManager.getConnection 会打开一个 Connection。
  • Statement 发送 SQL;executeQuery 返回 ResultSet,executeUpdate 返回受影响的行数。
  • 使用 rs.next() 和类型化读取方法进行迭代。
  • 始终使用资源自动管理,并结合其状态和错误代码处理 SQLException。

常见问题解答

「JDBC 基础」课时是免费的吗?

是的 — 「JDBC 基础」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「JDBC 基础」这节课中我会学到什么?

连接、语句与结果集 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「JDBC 基础」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. JDBC 基础
  2. PreparedStatement
  3. 事务
  4. 使用 HikariCP 实现连接池
← 返回 Java Academy