杰瑞科技汇

java对mysql数据库的操作

核心概念:JDBC

在 Java 中,我们通过 JDBC (Java Database Connectivity) 来与数据库进行交互,JDBC 是 Java 提供的一套标准 API,它定义了一组规则和接口,允许 Java 程序执行 SQL 语句并处理结果。

java对mysql数据库的操作-图1
(图片来源网络,侵删)

你可以把 JDBC 想象成一个“翻译官”或“中间人”:

  • Java 程序:说 Java 语言。
  • MySQL 数据库:说 SQL 语言。
  • JDBC:负责将 Java 的请求翻译成 SQL,发送给数据库,并将数据库返回的结果翻译成 Java 能理解的对象(如 ResultSet)。

准备工作

在开始编码之前,你需要准备好以下三样东西:

MySQL 数据库和表

确保你已经安装了 MySQL 数据库,并创建了一个数据库和一张用于测试的表。

-- 创建一个名为 `java_test` 的数据库
CREATE DATABASE java_test;
-- 使用该数据库
USE java_test;
-- 创建一个名为 `users` 的表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(50) NOT NULL,
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入一些测试数据
INSERT INTO users (username, password, email) VALUES
('alice', 'pass123', 'alice@example.com'),
('bob', 'bobpass', 'bob@example.com');

MySQL JDBC 驱动程序

Java 程序需要通过这个驱动才能与 MySQL 通信,你不需要手动下载 .jar 文件并添加到项目路径中,现代构建工具(如 Maven 或 Gradle)会自动处理。

Java 开发环境

一个标准的 Java 开发环境(JDK)和 IDE(如 IntelliJ IDEA 或 Eclipse)。


第一步:使用 Maven/Gradle 管理依赖

这是现代 Java 项目的标准做法,我们在 pom.xml (Maven) 或 build.gradle (Gradle) 文件中添加 MySQL 驱动的依赖。

Maven (pom.xml):

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

Gradle (build.gradle):

dependencies {
    // MySQL Connector/J 驱动
    implementation 'com.mysql:mysql-connector-j:8.0.33' // 建议使用最新稳定版
}

添加依赖后,你的构建工具会自动下载并配置好驱动。


第二步:编写 Java 代码进行数据库操作

我们将按照标准的步骤来编写代码,这些步骤是 JDBC 操作的通用流程。

加载驱动并建立连接

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcExample {
    // 数据库连接信息
    private static final String URL = "jdbc:mysql://localhost:3306/java_test?useSSL=false&serverTimezone=UTC";
    private static final String USER = "root"; // 你的数据库用户名
    private static final String PASSWORD = "your_password"; // 你的数据库密码
    public static void main(String[] args) {
        Connection connection = null;
        try {
            // 1. 加载驱动 (对于新版本的驱动,这步通常是可选的,但写上更明确)
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2. 建立连接
            System.out.println("正在连接数据库...");
            connection = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("数据库连接成功!");
            // ... 在这里执行数据库操作 ...
        } catch (ClassNotFoundException e) {
            System.err.println("找不到 MySQL JDBC 驱动类。");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("数据库连接或操作失败。");
            e.printStackTrace();
        } finally {
            // 3. 关闭连接 (非常重要!)
            if (connection != null) {
                try {
                    connection.close();
                    System.out.println("数据库连接已关闭。");
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

代码解释:

  • URL: 数据库的连接地址。
    • jdbc:mysql://: 协议和子协议。
    • localhost:3306: 数据库服务器的地址和端口。
    • /java_test: 要连接的数据库名。
    • ?useSSL=false&serverTimezone=UTC: 连接参数。useSSL=false 用于禁用 SSL(本地开发时常用),serverTimezone=UTC 指定时区,避免警告。
  • DriverManager.getConnection(): 这个静态方法会尝试使用所有已注册的驱动程序来建立连接。
  • try-catch-finally: 这是处理数据库资源的标准模式。finally 块确保无论是否发生异常,connection.close() 都会被执行,以释放数据库资源。

第三步:执行 SQL 语句

连接建立后,我们就可以执行 SQL 语句了,主要有三种操作:查询更新批处理

A. 查询操作 (SELECT)

使用 StatementPreparedStatement 来执行查询。强烈推荐使用 PreparedStatement,因为它可以防止 SQL 注入攻击,并且性能更好。

// ... (接上面的 main 方法,在 try 块内)
// 4. 创建 PreparedStatement 对象
String sql = "SELECT id, username, email FROM users WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 5. 设置参数 (索引从 1 开始)
preparedStatement.setInt(1, 1); // 设置第一个参数为 id=1
// 6. 执行查询,获取结果集
ResultSet resultSet = preparedStatement.executeQuery();
// 7. 处理结果集
while (resultSet.next()) { // .next() 移动到下一行,如果存在则返回 true
    int id = resultSet.getInt("id");
    String username = resultSet.getString("username");
    String email = resultSet.getString("email");
    System.out.printf("ID: %d, 用户名: %s, 邮箱: %s%n", id, username, email);
}
// 8. 关闭资源
resultSet.close();
preparedStatement.close();

B. 更新操作 (INSERT, UPDATE, DELETE)

更新操作不返回 ResultSet,而是返回一个整数,表示受影响的行数。

// ... (接上面的 main 方法,在 try 块内)
// 插入新用户
String insertSql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
PreparedStatement insertStatement = connection.prepareStatement(insertSql);
insertStatement.setString(1, "charlie");
insertStatement.setString(2, "charliepass");
insertStatement.setString(3, "charlie@example.com");
int rowsInserted = insertStatement.executeUpdate();
if (rowsInserted > 0) {
    System.out.println("新用户插入成功!");
}
insertStatement.close();
// 更新用户信息
String updateSql = "UPDATE users SET email = ? WHERE username = ?";
PreparedStatement updateStatement = connection.prepareStatement(updateSql);
updateStatement.setString(1, "alice_new@example.com");
updateStatement.setString(2, "alice");
int rowsUpdated = updateStatement.executeUpdate();
if (rowsUpdated > 0) {
    System.out.println("用户信息更新成功!");
}
updateStatement.close();

第四步:最佳实践 - 使用 try-with-resources (JDK 7+)

手动关闭 Connection, PreparedStatement, ResultSet 等资源非常繁琐,而且容易出错,JDK 7 引入了 try-with-resources 语句,它可以自动关闭实现了 AutoCloseable 接口(所有 JDBC 资源都实现了)的对象。

这是目前推荐的写法,代码更简洁、更安全。

import java.sql.*;
public class JdbcBestPractice {
    private static final String URL = "jdbc:mysql://localhost:3306/java_test?useSSL=false&serverTimezone=UTC";
    private static final String USER = "root";
    private static final String PASSWORD = "your_password";
    public static void main(String[] args) {
        // try-with-resources 会自动关闭 connection, preparedStatement, resultSet
        try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
             PreparedStatement preparedStatement = connection.prepareStatement("SELECT id, username FROM users");
             ResultSet resultSet = preparedStatement.executeQuery()) {
            System.out.println("数据库连接成功,开始查询...");
            while (resultSet.next()) {
                System.out.println("ID: " + resultSet.getInt("id") + 
                                   ", 用户名: " + resultSet.getString("username"));
            }
        } catch (SQLException e) {
            System.err.println("数据库操作出错!");
            e.printStackTrace();
        }
        // connection, preparedStatement, resultSet 都已自动关闭
    }
}

第五步:高级主题 - 连接池

每次操作数据库都创建和销毁连接是非常消耗资源的。连接池 应运而生,它预先创建一组数据库连接,并将其缓存起来,当需要时,从池中获取一个用完后再放回池中,而不是销毁。

这极大地提高了性能和响应速度。

添加连接池依赖

Maven (pom.xml):

<!-- HikariCP 是目前性能最好的连接池之一 -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.1</version>
</dependency>

使用 HikariCP 创建和管理连接

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JdbcWithPool {
    // 创建一个静态的连接池数据源
    private static HikariDataSource dataSource;
    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/java_test?useSSL=false&serverTimezone=UTC");
        config.setUsername("root");
        config.setPassword("your_password");
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
        // 连接池优化配置 (可选)
        config.setMaximumPoolSize(10); // 最大连接数
        config.setMinimumIdle(5);     // 最小空闲连接数
        config.setConnectionTimeout(30000); // 连接超时时间 (毫秒)
        dataSource = new HikariDataSource(config);
    }
    public static void main(String[] args) {
        // 从连接池获取一个连接
        try (Connection connection = dataSource.getConnection();
             PreparedStatement pstmt = connection.prepareStatement("SELECT username FROM users WHERE id = ?")) {
            pstmt.setInt(1, 1);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    System.out.println("查询到的用户名: " + rs.getString("username"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 在应用程序关闭时,关闭连接池
        if (dataSource != null && !dataSource.isClosed()) {
            dataSource.close();
        }
    }
}

第六步:现代框架 - JPA / MyBatis

虽然 JDBC 是基础,但在实际的企业级项目中,我们通常不会直接写这么多 JDBC 代码,而是使用 ORM(对象关系映射)框架或 SQL 映射框架来简化开发。

JPA (Java Persistence API) / Hibernate

  • 理念: 让你用 Java 对象来操作数据库,框架会自动将其转换为 SQL,你几乎不需要写原生 SQL。
  • 示例: 定义一个 User 实体类,然后通过 userRepository.findById(1L) 来查询用户,代码非常面向对象。
  • 优点: 开发效率高,代码可读性好,减少 SQL 书写量。
  • 缺点: 对于复杂查询,可能不如手写 SQL 灵活和高效。

MyBatis

  • 理念: 将 SQL 语句写在 XML 文件或注解中,Java 代码通过调用方法来执行这些预定义的 SQL。
  • 示例: 在 UserMapper.xml 中定义 <select id="selectUserById">...</select>,然后在 Java 代码中调用 userMapper.selectUserById(1)
  • 优点: SQL 与代码分离,便于维护和优化,对 SQL 的控制力非常强。
  • 缺点: 需要额外维护 SQL 文件,开发量比 JPA 稍多。

技术层次 技术名称 描述 适用场景
基础 JDBC Java 官方提供的数据库操作标准 API。 学习原理、简单工具、无框架项目。
最佳实践 JDBC + 连接池 在 JDBC 基础上,使用连接池(如 HikariCP)管理连接。 绝大多数 Java Web 应用的标准做法
高级 JPA / Hibernate ORM 框架,用 Java 对象操作数据库。 快速开发,业务逻辑为主的项目。
高级 MyBatis SQL 映射框架,灵活控制 SQL。 对 SQL 性能和灵活性要求高的项目。

对于初学者,务必掌握 JDBC 的基本原理和 try-with-resources 的用法学会使用连接池(如 HikariCP),这是从入门到进阶的关键一步,再根据项目需求学习 JPA 或 MyBatis 这样的框架。

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