1. 准备工作:安装必要的软件和驱动。
  2. JDBC 核心概念:了解几个关键接口和类。
  3. 编写第一个连接程序:一个完整的、可运行的示例。
  4. 代码详解:逐行解释代码的含义。
  5. 最佳实践:使用 try-with-resourcesPreparedStatement
  6. 常见问题与解决方案

第一步:准备工作

在开始编写 Java 代码之前,请确保你已经安装并配置好了以下环境:

java连接sql数据库教程
(图片来源网络,侵删)

安装 Java Development Kit (JDK)

确保你的电脑上已经安装了 JDK(推荐 JDK 8 或更高版本),并且配置好了 JAVA_HOME 环境变量和 Path 环境变量,你可以在命令行中输入 java -version 来验证。

安装 MySQL 数据库

如果你还没有安装 MySQL,请从 MySQL 官网 下载并安装,安装过程中请记住你的 root 用户密码

创建一个测试数据库和表

为了方便演示,我们登录到 MySQL,创建一个简单的数据库和一张表。

打开命令行(或 MySQL 自带的命令行客户端),执行以下 SQL 语句:

java连接sql数据库教程
(图片来源网络,侵删)
-- 创建一个名为 'testdb' 的数据库
CREATE DATABASE testdb;
-- 使用这个数据库
USE testdb;
-- 创建一张名为 'users' 的表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    age INT
);
-- 插入一些测试数据
INSERT INTO users (name, email, age) VALUES
('张三', 'zhangsan@example.com', 25),
('李四', 'lisi@example.com', 30),
('王五', 'wangwu@example.com', 28);

下载 MySQL JDBC 驱动

Java 程序需要通过一个“驱动程序”来与 MySQL 数据库通信,这个驱动程序是一个 .jar 文件。

  1. 访问 MySQL Connector/J 下载页面
  2. 选择 "Platform Independent" (平台独立) 版本。
  3. 下载 .zip.tar.gz 文件。
  4. 解压文件,你会找到一个名为 mysql-connector-j-版本号.jar 的文件。这个就是我们需要的驱动 JAR 包

第二步:JDBC 核心概念

在 Java 中,数据库操作是通过一套标准的 API 来实现的,这套 API JDBC,它定义了一组接口,具体的数据库厂商(如 MySQL, Oracle)会提供这些接口的实现类(即驱动)。

你需要了解的几个核心类和接口:

类/接口 作用
java.sql.Driver 驱动接口,每个数据库厂商都需要实现这个接口。
java.sql.DriverManager 驱动管理器,用于管理数据库驱动,并提供获取数据库连接的方法。
java.sql.Connection 连接接口,代表与数据库的一个连接会话。
java.sql.Statement 语句接口,用于执行静态的 SQL 语句。
java.sql.PreparedStatement 预编译语句接口,是 Statement 的子接口,用于执行预编译的 SQL 语句,防止 SQL 注入,效率更高
java.sql.ResultSet 结果集接口,用于存储数据库查询返回的数据。

第三步:编写第一个连接程序

我们将创建一个 Java 项目,实现连接数据库、查询数据并打印出来的功能。

java连接sql数据库教程
(图片来源网络,侵删)

创建 Java 项目并添加驱动库

  • 使用 IDE (如 IntelliJ IDEA 或 Eclipse):

    1. 创建一个新的 Java 项目。
    2. 右键点击项目 -> Open Module Settings / Properties -> Libraries / Java Build Path -> Libraries 选项卡。
    3. 点击 Add External JARs... 按钮,然后选择你下载的 mysql-connector-j-版本号.jar 文件。
    4. 点击 OK,这样,你的项目就能找到 MySQL 的驱动了。
  • 使用命令行 (手动管理):

    1. 创建一个项目文件夹,JdbcDemo
    2. 在文件夹内创建 src 文件夹来存放 .java 源文件。
    3. mysql-connector-j-版本号.jar 文件复制到 JdbcDemo 文件夹下。
    4. 编译时需要指定类路径(包含驱动 JAR 包):
      javac -cp ".;mysql-connector-j-版本号.jar" src/FirstConnection.java
    5. 运行时也需要指定类路径:
      java -cp ".;mysql-connector-j-版本号.jar" src.FirstConnection

      注意:在 Linux 或 macOS 上,路径分隔符是 而不是 。

编写 Java 代码

src 目录下创建一个名为 FirstConnection.java 的文件,并粘贴以下代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
public class FirstConnection {
    // 数据库连接信息
    // 注意:如果数据库不在本地,将 'localhost' 改为实际的 IP 地址
    private static final String DB_URL = "jdbc:mysql://localhost:3306/testdb";
    private static final String USER = "root";
    private static final String PASS = "你的MySQL密码"; // <-- 在这里填入你的 root 密码
    public static void main(String[] args) {
        // 1. 加载 JDBC 驱动
        // 在较新的 JDBC 版本中,这步通常是可选的,但写上更健壮
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            System.err.println("找不到 MySQL JDBC Driver!");
            e.printStackTrace();
            return;
        }
        // 2. 建立数据库连接
        // 使用 try-with-resources 语句,确保 Connection, Statement, ResultSet 在使用后自动关闭
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT id, name, email, age FROM users")) {
            System.out.println("成功连接到数据库!");
            // 3. 处理查询结果
            System.out.println("ID\t姓名\t\t邮箱\t\t年龄");
            System.out.println("---------------------------------------------");
            while (rs.next()) {
                // 通过列名获取数据,更推荐
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String email = rs.getString("email");
                int age = rs.getInt("age");
                // 打印出每一行数据
                System.out.printf("%d\t%s\t\t%s\t\t%d\n", id, name, email, age);
            }
        } catch (SQLException e) {
            System.err.println("数据库连接或查询出错!");
            e.printStackTrace();
        }
    }
}

运行程序

运行 FirstConnection.java,如果一切顺利,你将在控制台看到类似下面的输出:

成功连接到数据库!
ID  姓名      邮箱      年龄
---------------------------------------------
1   张三      zhangsan@example.com    25
2   李四      lisi@example.com    30
3   王五      wangwu@example.com  28

第四步:代码详解

// 1. 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
  • 这行代码的作用是加载 MySQL 的 JDBC 驱动类,驱动类在被加载时,会自动向 DriverManager 注册自己。
  • 注意:对于 MySQL Connector/J 8.x 版本,驱动类名是 com.mysql.cj.jdbc.Driver,旧版本可能是 com.mysql.jdbc.Driver
// 2. 建立连接
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
  • DriverManager.getConnection() 是获取数据库连接的核心方法。
  • 它需要三个参数:数据库 URL、用户名和密码。
  • URL 格式jdbc:mysql://主机名:端口号/数据库名
    • jdbc:mysql://: 协议和子协议。
    • localhost: 数据库服务器地址,本地就是 localhost
    • 3306: MySQL 的默认端口号。
    • testdb: 我们要连接的数据库名。
    • 附加参数:通常我们还会在 URL 后面添加一些参数,?useSSL=false&serverTimezone=UTCuseSSL=false 用于禁用 SSL(在开发环境中常见),serverTimezone=UTC 用于指定时区。
// 3. 创建 Statement
Statement stmt = conn.createStatement();
  • Connection 对象的 createStatement() 方法用于创建一个 Statement 对象,它用来执行 SQL 语句。
// 4. 执行查询
ResultSet rs = stmt.executeQuery("SELECT id, name, email, age FROM users");
  • Statement.executeQuery() 方法用于执行一个会返回结果集的 SQL 查询语句(如 SELECT)。
  • 它返回一个 ResultSet 对象,包含了查询的所有数据。
// 5. 遍历结果集
while (rs.next()) {
    // ...
}
  • ResultSet 是一个指向数据行的“光标”,它最初位于第一行之前
  • rs.next() 方法将光标移动到下一行,如果成功移动(即还有下一行),则返回 true;否则返回 false
  • 我们使用 while 循环来遍历所有的行。
// 6. 获取数据
int id = rs.getInt("id");
String name = rs.getString("name");
  • rs.getXXX("列名") 方法用于获取当前行指定列的数据。
  • XXX 是数据类型,如 getInt(), getString(), getDate() 等。
  • 强烈推荐使用列名而不是列索引(如 rs.getInt(1)),因为代码更具可读性,并且在 SQL 查询顺序改变时不易出错。

第五步:最佳实践

上面的示例是基础版,但在实际生产环境中,我们应该遵循以下最佳实践。

使用 try-with-resources (资源管理)

上面的代码已经使用了 try-with-resources,这是 Java 7 引入的一个特性,可以自动关闭实现了 AutoCloseable 接口的对象(如 Connection, Statement, ResultSet),即使在 try 代码块中发生了异常,这可以防止资源泄漏,是现代 Java 编程的标准做法。

使用 PreparedStatement 防止 SQL 注入

Statement 用于执行静态 SQL,SQL 语句中包含用户输入,就可能导致 SQL 注入攻击。PreparedStatement 用于执行预编译的 SQL,它会把 SQL 语句和数据分开处理,从而有效防止 SQL 注入。

示例:使用 PreparedStatement 进行参数化查询

import java.sql.*;
public class PreparedStatementExample {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/testdb";
    private static final String USER = "root";
    private static final String PASS = "你的MySQL密码";
    public static void main(String[] args) {
        String searchName = "张三"; // 模拟从用户输入获取
        // SQL 语句中使用 ? 作为占位符
        String sql = "SELECT id, name, email, age FROM users WHERE name = ?";
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             // 创建 PreparedStatement 对象
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // 设置参数,索引从 1 开始
            pstmt.setString(1, searchName);
            // 执行查询
            try (ResultSet rs = pstmt.executeQuery()) {
                System.out.println("查找用户: " + searchName);
                System.out.println("ID\t姓名\t\t邮箱\t\t年龄");
                System.out.println("---------------------------------------------");
                while (rs.next()) {
                    System.out.printf("%d\t%s\t\t%s\t\t%d\n",
                            rs.getInt("id"),
                            rs.getString("name"),
                            rs.getString("email"),
                            rs.getInt("age"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

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

ClassNotFoundException: com.mysql.cj.jdbc.Driver

  • 原因:JDBC 驱动 JAR 包没有添加到项目的类路径中。
  • 解决:检查你的 IDE 项目设置或命令行的 -cp 参数,确保 mysql-connector-j-*.jar 文件被正确包含。

Communications link failure

  • 原因:无法连接到数据库服务器。
    • MySQL 服务没有启动。
    • 数据库地址或端口号错误(不是 localhost:3306)。
    • 防火墙阻止了连接。
    • 数据库用户名或密码错误。
  • 解决
    1. 确保你的 MySQL 服务正在运行(可以通过任务管理器或服务面板检查)。
    2. 检查 DB_URL 中的主机和端口是否正确。
    3. 尝试使用 telnet <主机地址> <端口号> 来测试网络连通性。
    4. 再次确认用户名和密码。

Access denied for user 'root'@'localhost'

  • 原因:提供的用户名或密码不正确。
  • 解决:检查代码中的 USERPASS 变量,确保它们与你的 MySQL 用户凭据完全匹配,如果你忘记了密码,可能需要重置 MySQL 的 root 密码。

No database selected

  • 原因DB_URL 中没有指定数据库名,或者指定的数据库不存在。
  • 解决:检查 DB_URL 字符串,确保末尾包含了你的数据库名,/testdb,然后登录 MySQL 确认该数据库是否存在。

通过本教程,你已经学会了如何使用 Java 和 JDBC 连接到 MySQL 数据库,并执行基本的查询操作,核心步骤可以总结为:

  1. 加载驱动 (Class.forName)。
  2. 获取连接 (DriverManager.getConnection)。
  3. 创建语句 (Connection.createStatementprepareStatement)。
  4. 执行语句 (executeQuery, executeUpdate 等)。
  5. 处理结果 (ResultSet)。
  6. 关闭资源 (使用 try-with-resources 自动完成)。

在实际项目中,你还会接触到数据库连接池(如 HikariCP, Druid)来管理数据库连接,以提高性能和稳定性,但 JDBC 的基本原理是学习一切数据库操作的基础。