java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > JDBC连接数据库

从零开始手写JDBC连接数据库的详细指南

作者:超级小忍

在 Java 开发中,数据库是存储和管理数据的核心组件,JDBC是 Java 程序与数据库交互的标准 API,本文将带大家手写一个完整的 JDBC 连接数据库的示例,希望对大家有所帮助

前言

在 Java 开发中,数据库是存储和管理数据的核心组件。而 JDBC(Java Database Connectivity)是 Java 程序与数据库交互的标准 API,它允许 Java 应用程序连接各种关系型数据库(如 MySQL、Oracle、PostgreSQL 等),并执行 SQL 语句。虽然现代开发中常使用 ORM 框架(如 MyBatis、Hibernate)简化数据库操作,但理解 JDBC 的底层原理对于深入掌握数据库编程至关重要。

本文将带你手写一个完整的 JDBC 连接数据库的示例,涵盖从环境准备到代码实现的每一个细节,力求做到“越详细越好”。

一、环境准备

在开始编码之前,确保你的开发环境已准备好以下工具和资源:

1.JDK(Java Development Kit)

2.数据库

3.数据库驱动(JDBC Driver)

JDBC 需要特定数据库的驱动程序来实现与数据库的通信。对于 MySQL,需要mysql-connector-java驱动。

下载驱动

获取 JAR 文件:解压下载的 ZIP 文件,找到mysql-connector-java-x.x.x.jar文件(x.x.x是版本号,如8.0.33)。

将 JAR 文件添加到项目

传统项目:将 JAR 文件复制到项目的lib目录下,并在 IDE(如 IntelliJ IDEA, Eclipse)中将其添加为项目的库(Library)。

Maven 项目:在pom.xml中添加依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version> <!-- 使用最新稳定版本 -->
</dependency>

Gradle 项目:在build.gradle中添加:

implementation 'mysql:mysql-connector-java:8.0.33'

4.数据库和表准备

启动 MySQL 服务。

使用 MySQL 客户端(如命令行mysql、MySQL Workbench)创建一个数据库和一张表。例如:

-- 创建数据库
CREATE DATABASE IF NOT EXISTS demo_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 使用数据库
USE demo_db;

-- 创建用户表
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(150) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入测试数据
INSERT INTO users (name, email) VALUES
('张三', 'zhangsan@example.com'),
('李四', 'lisi@example.com'),
('王五', 'wangwu@example.com');

记下数据库名demo_db,表名users,以及你用于连接的用户名(如root)和密码。

二、JDBC 核心组件与连接流程

JDBC 的核心组件主要包括:

JDBC 标准连接流程

三、手写 JDBC 代码实现

我们将创建一个简单的 Java 程序,完成以下操作:

步骤 1:创建 Java 项目和类

创建一个名为JDBCDemo的 Java 类。

步骤 2:编写代码

import java.sql.*;

/**
 * 手写JDBC连接数据库示例
 * 演示连接MySQL、查询、插入操作
 */
public class JDBCDemo {

    // 数据库连接信息 - 请根据实际情况修改
    private static final String DB_URL = "jdbc:mysql://localhost:3306/demo_db?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8";
    private static final String USER = "your_username"; // 替换为你的MySQL用户名
    private static final String PASSWORD = "your_password"; // 替换为你的MySQL密码

    // JDBC驱动类名 (MySQL 8.0+)
    private static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";

    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        PreparedStatement preparedStatement = null;

        try {
            // ========== 步骤1:加载JDBC驱动 (可选,现代JDBC通常自动加载) ==========
            // 显式加载驱动类,确保驱动被注册到DriverManager
            // 对于JDBC 4.0+ (Java 6+),通常不需要这一步,驱动会自动发现和加载
            // 但显式加载可以确保兼容性或在特定环境下工作
            Class.forName(DRIVER_CLASS);
            System.out.println("JDBC驱动加载成功!");

            // ========== 步骤2:建立数据库连接 ==========
            System.out.println("正在连接数据库...");
            connection = DriverManager.getConnection(DB_URL, USER, PASSWORD);
            System.out.println("数据库连接成功!");

            // ========== 步骤3:创建Statement对象 ==========
            statement = connection.createStatement();

            // ========== 步骤4:执行查询SQL并处理结果 ==========
            System.out.println("\n--- 查询所有用户信息 ---");
            String selectSql = "SELECT id, name, email, created_at FROM users";
            resultSet = statement.executeQuery(selectSql); // executeQuery用于SELECT

            // 处理ResultSet
            System.out.printf("%-5s %-15s %-25s %-20s%n", "ID", "姓名", "邮箱", "创建时间");
            System.out.println("------------------------------------------------------------");
            while (resultSet.next()) {
                int id = resultSet.getInt("id"); // 根据列名获取int值
                String name = resultSet.getString("name"); // 根据列名获取String值
                String email = resultSet.getString("email");
                Timestamp createdAt = resultSet.getTimestamp("created_at");

                // 格式化输出
                System.out.printf("%-5d %-15s %-25s %-20s%n", id, name, email, createdAt);
            }

            // ========== 步骤5:使用PreparedStatement执行插入操作 (防止SQL注入) ==========
            System.out.println("\n--- 准备插入新用户 ---");
            String insertSql = "INSERT INTO users (name, email) VALUES (?, ?)";
            preparedStatement = connection.prepareStatement(insertSql); // 使用PreparedStatement

            // 设置参数值 (索引从1开始)
            preparedStatement.setString(1, "赵六");
            preparedStatement.setString(2, "zhaoliu@example.com");

            // 执行插入
            int rowsAffected = preparedStatement.executeUpdate(); // executeUpdate用于INSERT, UPDATE, DELETE
            System.out.println("插入操作完成,影响了 " + rowsAffected + " 行。");

            // ========== 步骤6:再次查询,验证插入结果 ==========
            System.out.println("\n--- 再次查询所有用户信息 (验证插入) ---");
            // 重新执行查询
            resultSet.close(); // 关闭之前的ResultSet
            resultSet = statement.executeQuery(selectSql);

            System.out.printf("%-5s %-15s %-25s %-20s%n", "ID", "姓名", "邮箱", "创建时间");
            System.out.println("------------------------------------------------------------");
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                String email = resultSet.getString("email");
                Timestamp createdAt = resultSet.getTimestamp("created_at");
                System.out.printf("%-5d %-15s %-25s %-20s%n", id, name, email, createdAt);
            }

        } catch (ClassNotFoundException e) {
            System.err.println("JDBC驱动类未找到!请检查驱动JAR是否在类路径中。");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("数据库操作发生错误!");
            e.printStackTrace();
        } finally {
            // ========== 步骤7:关闭资源 (非常重要!) ==========
            // 必须在finally块中关闭,确保即使发生异常也能释放资源
            // 关闭顺序:ResultSet -> Statement/PreparedStatement -> Connection
            try {
                if (resultSet != null) {
                    resultSet.close();
                    System.out.println("ResultSet已关闭。");
                }
            } catch (SQLException e) {
                System.err.println("关闭ResultSet时出错!");
                e.printStackTrace();
            }

            try {
                if (statement != null) {
                    statement.close();
                    System.out.println("Statement已关闭。");
                }
            } catch (SQLException e) {
                System.err.println("关闭Statement时出错!");
                e.printStackTrace();
            }

            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                    System.out.println("PreparedStatement已关闭。");
                }
            } catch (SQLException e) {
                System.err.println("关闭PreparedStatement时出错!");
                e.printStackTrace();
            }

            try {
                if (connection != null) {
                    connection.close();
                    System.out.println("数据库连接已关闭。");
                }
            } catch (SQLException e) {
                System.err.println("关闭Connection时出错!");
                e.printStackTrace();
            }
        }

        System.out.println("JDBC演示程序结束。");
    }
}

四、代码详解与关键点

1.数据库 URL (DB_URL)

2.Class.forName(DRIVER_CLASS)

3.DriverManager.getConnection()

这是获取Connection对象的核心方法。它会遍历已注册的驱动,找到能处理给定 URL 的驱动,并建立连接。

4.Statement vs PreparedStatement

5.执行方法

6.ResultSet处理

7.资源关闭 (try-catch-finally)

五、运行与测试

将代码中的USERPASSWORD替换为你实际的 MySQL 用户名和密码。

确保mysql-connector-java-x.x.x.jar已正确添加到项目的类路径。

编译并运行JDBCDemo类。

观察控制台输出,应该能看到连接成功、查询结果、插入成功以及再次查询的结果。

六、常见问题与注意事项

ClassNotFoundException: 找不到驱动类。检查:

SQLException: 数据库连接失败。检查:

中文乱码: 确保数据库、表、字段的字符集是utf8mb4,并且 JDBC URL 中包含useUnicode=true&characterEncoding=utf8

资源泄漏: 务必在finally块中关闭所有 JDBC 资源。

SQL 注入: 永远不要使用Statement拼接用户输入的字符串。始终使用PreparedStatement

性能: 对于频繁执行的相同 SQL,使用PreparedStatement可以预编译,提高效率。

七、总结

通过本文,我们从零开始手写了一个完整的 JDBC 程序,涵盖了驱动加载、连接建立、SQL 执行(查询和插入)、结果处理以及至关重要的资源管理。虽然现代开发更多依赖于高级框架,但掌握 JDBC 的底层机制,能让你更深刻地理解数据库交互的原理,有助于排查问题、优化性能,并在需要时进行底层定制。

记住核心要点:加载驱动(可选) -> 获取连接 -> 创建语句 -> 执行 SQL -> 处理结果 -> 关闭资源(务必!)。

以上就是从零开始手写JDBC连接数据库的详细指南的详细内容,更多关于JDBC连接数据库的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文