杰瑞科技汇

Java连接MySQL数据库代码有哪些关键步骤?

准备工作

在编写代码之前,您需要完成以下准备工作:

Java连接MySQL数据库代码有哪些关键步骤?-图1
(图片来源网络,侵删)

安装 MySQL 数据库

确保您的计算机上已经安装并运行了 MySQL 数据库,如果没有,请从 MySQL 官网 下载并安装。

创建数据库和表

登录到您的 MySQL 服务器(可以使用命令行或如 MySQL Workbench, Navicat 等图形化工具),创建一个示例数据库和一张用于测试的表。

-- 创建一个名为 `jdbc_test` 的数据库
CREATE DATABASE jdbc_test;
-- 使用这个数据库
USE jdbc_test;
-- 创建一张名为 `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
('Alice', 'alice@example.com', 28),
('Bob', 'bob@example.com', 32),
('Charlie', 'charlie@example.com', 24);

获取数据库连接信息

记下以下信息,后续代码中会用到:

  • 主机名: 通常是 localhost (如果数据库在本地运行)
  • 端口: 默认是 3306
  • 数据库名: jdbc_test
  • 用户名: 您的 MySQL 用户名 (root)
  • 密码: 您的 MySQL 密码

添加 MySQL JDBC 驱动

Java 程序需要通过 JDBC 驱动来与 MySQL 数据库通信,您需要下载 MySQL Connector/J(这是官方的 JDBC 驱动)。

Java连接MySQL数据库代码有哪些关键步骤?-图2
(图片来源网络,侵删)

推荐方式:使用 Maven 或 Gradle(现代项目首选)

如果您使用 Maven,在您的 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version> <!-- 建议使用最新稳定版 -->
</dependency>

如果您使用 Gradle,在您的 build.gradle 文件中添加:

implementation 'com.mysql:mysql-connector-j:8.0.33' // 建议使用最新稳定版

手动方式(不推荐,但适用于简单项目)

Java连接MySQL数据库代码有哪些关键步骤?-图3
(图片来源网络,侵删)
  1. 访问 MySQL Connector/J 下载页面
  2. 下载 Platform Independent 版本的 ZIP 文件。
  3. 解压后,找到 mysql-connector-j-<version>.jar 文件。
  4. 在您的 Java IDE(如 IntelliJ IDEA 或 Eclipse)中,将此 JAR 文件添加到项目的类路径(Classpath)中。

第二步:编写 Java 代码

我们将创建一个完整的 Java 类,演示如何执行基本的数据库操作:查询、插入、更新和删除

这里我们使用 JDBC 4.0+ 的标准方式,它不需要显式地加载驱动类,驱动管理器会自动处理。

完整代码示例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MysqlJdbcExample {
    // --- 数据库连接信息 ---
    // 请根据您的实际情况修改这些值
    private static final String DB_URL = "jdbc:mysql://localhost:3306/jdbc_test?useSSL=false&serverTimezone=UTC";
    private static final String USER = "root";       // 您的数据库用户名
    private static final String PASS = "your_password"; // 您的数据库密码
    public static void main(String[] args) {
        // 使用 try-with-resources 语句,确保资源在使用后被自动关闭
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
            System.out.println("成功连接到数据库!");
            // 1. 查询数据
            System.out.println("\n--- 查询所有用户 ---");
            selectAllUsers(conn);
            // 2. 插入数据
            System.out.println("\n--- 插入一个新用户 ---");
            insertUser(conn, "David", "david@example.com", 40);
            // 再次查询以验证插入
            selectAllUsers(conn);
            // 3. 更新数据
            System.out.println("\n--- 更新用户 'Alice' 的年龄 ---");
            updateUserAge(conn, "Alice", 29);
            selectAllUsers(conn);
            // 4. 删除数据
            System.out.println("\n--- 删除用户 'Bob' ---");
            deleteUser(conn, "Bob");
            selectAllUsers(conn);
        } catch (SQLException e) {
            System.err.println("数据库连接或操作失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
    /**
     * 查询并打印所有用户
     */
    private static void selectAllUsers(Connection conn) throws SQLException {
        String sql = "SELECT id, name, email, age FROM users";
        // Statement 用于执行静态 SQL 语句
        try (Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            System.out.println("ID | Name      | Email               | Age");
            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  | %-9s | %-19s | %d%n", id, name, email, age);
            }
        }
    }
    /**
     * 使用 PreparedStatement 插入新用户(防止 SQL 注入)
     */
    private static void insertUser(Connection conn, String name, String email, int age) throws SQLException {
        String sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
        // PreparedStatement 用于执行预编译的 SQL 语句,防止 SQL 注入
        try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // 设置参数 (索引从 1 开始)
            pstmt.setString(1, name);
            pstmt.setString(2, email);
            pstmt.setInt(3, age);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("成功插入 " + affectedRows + " 行数据。");
        }
    }
    /**
     * 更新用户年龄
     */
    private static void updateUserAge(Connection conn, String name, int newAge) throws SQLException {
        String sql = "UPDATE users SET age = ? WHERE name = ?";
        try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, newAge);
            pstmt.setString(2, name);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("成功更新 " + affectedRows + " 行数据。");
        }
    }
    /**
     * 删除用户
     */
    private static void deleteUser(Connection conn, String name) throws SQLException {
        String sql = "DELETE FROM users WHERE name = ?";
        try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, name);
            int affectedRows = pstmt.executeUpdate();
            System.out.println("成功删除 " + affectedRows + " 行数据。");
        }
    }
}

代码详解

  1. 数据库连接信息:

    • DB_URL: JDBC URL 格式为 jdbc:mysql://[host]:[port]/[database_name]
      • ?useSSL=false: 在本地开发时可以禁用 SSL 以避免警告。
      • &serverTimezone=UTC: 设置服务器时区,避免时区警告。
    • USERPASS: 您的 MySQL 用户名和密码。
  2. DriverManager.getConnection():

    • 这是建立数据库连接的核心方法,它接受 URL、用户名和密码作为参数,并返回一个 Connection 对象,代表与数据库的会话。
  3. try-with-resources 语句:

    • 这是 Java 7 引入的一个非常实用的特性,它会自动实现 AutoCloseable 接口的资源(如 Connection, Statement, ResultSet)在语句块结束时被关闭,无需手动调用 close() 方法,有效避免了资源泄漏。
  4. 查询数据 (selectAllUsers):

    • Statement: 用于执行不带参数的简单 SQL 查询。
    • executeQuery(sql): 执行 SELECT 查询,返回一个 ResultSet 对象,该对象包含了查询结果。
    • ResultSet: 一个指向结果集数据行的游标。rs.next() 将游标移动到下一行,如果存在下一行则返回 true
    • rs.getXXX(): 从当前行获取列的值,可以使用列名(如 rs.getString("name"))或列索引(如 rs.getString(2)),推荐使用列名,因为代码更清晰,且当 SQL 查询的列顺序改变时不易出错。
  5. 增删改数据 (insertUser, updateUserAge, deleteUser):

    • PreparedStatement: 用于执行带参数的 SQL 语句,它将 SQL 语句预编译,然后通过 setXXX() 方法设置参数值。
    • 优点:
      • 性能高: 如果同一条 SQL 语句需要多次执行,只需编译一次,效率更高。
      • 安全性高: 能有效防止 SQL 注入攻击,因为它会将参数值作为数据处理,而不是 SQL 语句的一部分。
    • executeUpdate(): 用于执行 INSERT, UPDATE, DELETE 等会改变数据库数据的 SQL 语句,返回一个整数,表示受影响的行数。
  6. 异常处理 (SQLException):

    • 所有 JDBC 操作都可能抛出 SQLException,必须用 try-catch 块处理它,以便在发生错误时能够捕获并处理。

运行结果

在您修改了代码中的数据库连接信息(用户名和密码)后,运行该 MysqlJdbcExample 类,您将看到类似以下的输出:

成功连接到数据库!
--- 查询所有用户 ---
ID | Name      | Email               | Age
------------------------------------------
1  | Alice     | alice@example.com   | 28
2  | Bob       | bob@example.com     | 32
3  | Charlie   | charlie@example.com | 24
--- 插入一个新用户 ---
成功插入 1 行数据。
--- 查询所有用户 ---
ID | Name      | Email               | Age
------------------------------------------
1  | Alice     | alice@example.com   | 28
2  | Bob       | bob@example.com     | 32
3  | Charlie   | charlie@example.com | 24
4  | David     | david@example.com   | 40
--- 更新用户 'Alice' 的年龄 ---
成功更新 1 行数据。
--- 查询所有用户 ---
ID | Name      | Email               | Age
------------------------------------------
1  | Alice     | alice@example.com   | 29
2  | Bob       | bob@example.com     | 32
3  | Charlie   | charlie@example.com | 24
4  | David     | david@example.com   | 40
--- 删除用户 'Bob' ---
成功删除 1 行数据。
--- 查询所有用户 ---
ID | Name      | Email               | Age
------------------------------------------
1  | Alice     | alice@example.com   | 29
3  | Charlie   | charlie@example.com | 24
4  | David     | david@example.com   | 40

总结与最佳实践

  • 总是使用 PreparedStatement: 除非您 100% 确定您的 SQL 语句是静态的且不会受到外部输入的影响,否则永远不要使用 StatementPreparedStatement 是更安全、更高效的选择。
  • 总是使用 try-with-resources: 这是管理 JDBC 资源(连接、语句、结果集)的现代标准做法,能极大地简化代码并避免资源泄漏。
  • 不要硬编码凭证: 在实际生产环境中,不要将数据库用户名和密码直接写在代码里,应该使用配置文件(如 config.properties)、环境变量或专门的密钥管理服务来管理敏感信息。
  • 考虑连接池: 对于高并发的应用,频繁地创建和销毁数据库连接是非常消耗资源的,应该使用连接池(如 HikariCP, C3P0, DBCP)来管理和复用数据库连接。
分享:
扫描分享到社交APP
上一篇
下一篇