杰瑞科技汇

Java MySQL教程如何快速入门?

Java 连接 MySQL 数据库完整教程

本教程将涵盖以下内容:

Java MySQL教程如何快速入门?-图1
(图片来源网络,侵删)
  1. 环境准备: 安装和配置必要的软件。
  2. 创建数据库和表: 在 MySQL 中准备数据。
  3. 添加 JDBC 驱动: 将 MySQL 的驱动程序引入你的 Java 项目。
  4. JDBC 编程基础: 连接、执行查询、处理结果、关闭资源的标准流程。
  5. 核心代码示例: 提供增、删、改、查 的完整代码。
  6. 最佳实践: 使用 try-with-resources 和 PreparedStatement。
  7. 项目实战: 一个简单的控制台 CRUD 应用。

第一步:环境准备

在开始之前,请确保你已经安装并配置好了以下软件:

  1. Java Development Kit (JDK): 确保你的系统上已安装 JDK 8 或更高版本,可以通过 java -versionjavac -version 命令检查。
  2. MySQL Server: 确保你的系统上已安装并运行了 MySQL 数据库,可以通过 mysql -u root -p 命令登录来验证。
  3. IDE (集成开发环境): 推荐使用 IntelliJ IDEA 或 Eclipse,它们能极大地简化开发过程。

第二步:创建数据库和表

打开你的 MySQL 客户端(如 MySQL Workbench, Navicat, 或命令行),执行以下 SQL 语句来创建一个数据库和一张用于测试的表。

-- 创建一个名为 `jdbc_demo` 的数据库
CREATE DATABASE IF NOT EXISTS jdbc_demo;
-- 使用这个数据库
USE jdbc_demo;
-- 创建一张 `users` 表
CREATE TABLE IF NOT EXISTS 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
('zhangsan', '123456', 'zhangsan@example.com'),
('lisi', '654321', 'lisi@example.com');

第三步:添加 MySQL JDBC 驱动

Java 程序需要通过一个“桥梁”(即 JDBC 驱动)来与 MySQL 数据库通信,你需要将 MySQL 提供的 JDBC 驱动 JAR 文件添加到你的项目中。

Maven 项目 (推荐)

如果你使用 Maven,这是最简单、最推荐的方式,只需在 pom.xml 文件中添加 MySQL 驱动的依赖。

Java MySQL教程如何快速入门?-图2
(图片来源网络,侵删)
<dependencies>
    <!-- MySQL Connector/J 驱动 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version> <!-- 建议使用最新稳定版 -->
    </dependency>
</dependencies>

添加后,Maven 会自动下载并管理这个依赖。

手动下载 JAR

  1. 访问 MySQL Connector/J 下载页面
  2. 选择 "Platform Independent" (平台独立) 的 ZIP Archive 下载并解压。
  3. 在你的 IDE 中,右键点击项目 -> "Build Path" / "Project Structure" -> "Libraries" -> "Add External JARs...",然后选择解压后的 mysql-connector-j-8.0.xx.jar 文件。

第四步:JDBC 编程基础

所有 JDBC 操作都遵循一个固定的模式:

  1. 加载驱动: 告诉 JVM 使用哪个数据库驱动。
  2. 获取连接: 使用数据库 URL、用户名和密码建立与数据库的连接。
  3. 创建语句: 通过连接对象创建 StatementPreparedStatement 对象,用于执行 SQL。
  4. 执行 SQL: 调用 executeQuery() (用于查询) 或 executeUpdate() (用于增、删、改) 方法。
  5. 处理结果集: 如果是查询操作,遍历 ResultSet 对象来获取数据。
  6. 关闭资源: 按照相反的顺序关闭 ResultSetStatementConnection(非常重要!)

第五步:核心代码示例

数据库连接信息

建议将这些信息放在一个单独的常量类或配置文件中,这里为了方便,我们直接写在代码里。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
    // 数据库 URL
    // 格式: jdbc:mysql://[主机名]:[端口号]/[数据库名]?[参数]
    // useSSL=false (或 true) 用于禁用/启用 SSL 连接,根据你的 MySQL 版本配置
    // useUnicode=true&characterEncoding=UTF-8 确保支持中文等特殊字符
    private static final String URL = "jdbc:mysql://localhost:3306/jdbc_demo?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8";
    private static final String USER = "root"; // 你的 MySQL 用户名
    private static final String PASSWORD = "your_password"; // 你的 MySQL 密码
    // 获取数据库连接
    public static Connection getConnection() {
        Connection connection = null;
        try {
            // 1. 加载驱动 (对于新版驱动,这步可以省略,但保留它更明确)
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2. 获取连接
            connection = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("数据库连接成功!");
        } catch (ClassNotFoundException e) {
            System.err.println("MySQL JDBC Driver not found.");
            e.printStackTrace();
        } catch (SQLException e) {
            System.err.println("Connection Failed. Check output console");
            e.printStackTrace();
        }
        return connection;
    }
    // 关闭数据库连接
    public static void closeConnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
                System.out.println("数据库连接已关闭。");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

查询数据

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class SelectExample {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            // 1. 获取连接
            conn = DBUtil.getConnection();
            // 2. 创建 Statement
            stmt = conn.createStatement();
            // 3. 执行查询
            String sql = "SELECT id, username, email FROM users";
            rs = stmt.executeQuery(sql);
            // 4. 处理结果集
            System.out.println("ID\tUsername\tEmail");
            System.out.println("----------------------------------");
            while (rs.next()) {
                // 通过列名获取数据,更推荐
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String email = rs.getString("email");
                System.out.println(id + "\t" + username + "\t\t" + email);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭资源 (非常重要!)
            // 关闭顺序: ResultSet -> Statement -> Connection
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) DBUtil.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

插入数据

import java.sql.Connection;
import java.sql.Statement;
public class InsertExample {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = DBUtil.getConnection();
            stmt = conn.createStatement();
            String sql = "INSERT INTO users (username, password, email) VALUES ('wangwu', 'password123', 'wangwu@example.com')";
            // executeUpdate() 返回受影响的行数
            int affectedRows = stmt.executeUpdate(sql);
            if (affectedRows > 0) {
                System.out.println("成功插入 " + affectedRows + " 行数据。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) stmt.close();
                if (conn != null) DBUtil.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

更新数据

import java.sql.Connection;
import java.sql.Statement;
public class UpdateExample {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = DBUtil.getConnection();
            stmt = conn.createStatement();
            String sql = "UPDATE users SET email = 'new_lisi@example.com' WHERE username = 'lisi'";
            int affectedRows = stmt.executeUpdate(sql);
            if (affectedRows > 0) {
                System.out.println("成功更新 " + affectedRows + " 行数据。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) stmt.close();
                if (conn != null) DBUtil.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

删除数据

import java.sql.Connection;
import java.sql.Statement;
public class DeleteExample {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = DBUtil.getConnection();
            stmt = conn.createStatement();
            String sql = "DELETE FROM users WHERE username = 'wangwu'";
            int affectedRows = stmt.executeUpdate(sql);
            if (affectedRows > 0) {
                System.out.println("成功删除 " + affectedRows + " 行数据。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) stmt.close();
                if (conn != null) DBUtil.closeConnection(conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

第六步:最佳实践

使用 try-with-resources (Java 7+)

手动关闭资源 (try-catch-finally) 很繁琐且容易出错,Java 7 引入了 try-with-resources 语句,它可以自动实现资源的关闭,任何实现了 AutoCloseable 接口的类都可以使用它。

重构后的查询代码 (更推荐):

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class SelectExampleWithTryWithResources {
    public static void main(String[] args) {
        // try-with-resources 会自动关闭 conn, stmt, rs
        try (Connection conn = DBUtil.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT id, username, email FROM users")) {
            System.out.println("ID\tUsername\tEmail");
            System.out.println("----------------------------------");
            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String email = rs.getString("email");
                System.out.println(id + "\t" + username + "\t\t" + email);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // conn, stmt, rs 在这里会自动被关闭,无需手动操作
    }
}

使用 PreparedStatement 防止 SQL 注入

Statement 在拼接 SQL 字符串时容易引发 SQL 注入攻击。PreparedStatement 是预编译的 SQL 语句,它使用 作为占位符,可以更安全、更高效地处理参数。

使用 PreparedStatement 的插入示例:

import java.sql.Connection;
import java.sql.PreparedStatement;
public class InsertWithPreparedStatement {
    public static void main(String[] args) {
        String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
        // try-with-resources 确保 PreparedStatement 和 Connection 被自动关闭
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // 设置参数 (索引从 1 开始)
            pstmt.setString(1, "zhaoliu");
            pstmt.setString(2, "safe_password");
            pstmt.setString(3, "zhaoliu@example.com");
            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                System.out.println("成功插入 " + affectedRows + " 行数据。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

第七步:项目实战 - 简单的 CRUD 控制台应用

这是一个综合运用上述知识的简单示例,用户可以通过命令行对 users 表进行增删改查。

import java.sql.*;
import java.util.Scanner;
public class SimpleCRUDApp {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("\n--- 用户管理系统 ---");
            System.out.println("1. 查看所有用户");
            System.out.println("2. 添加新用户");
            System.out.println("3. 更新用户信息");
            System.out.println("4. 删除用户");
            System.out.println("5. 退出");
            System.out.print("请选择操作: ");
            int choice = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符
            switch (choice) {
                case 1:
                    listUsers();
                    break;
                case 2:
                    addUser(scanner);
                    break;
                case 3:
                    updateUser(scanner);
                    break;
                case 4:
                    deleteUser(scanner);
                    break;
                case 5:
                    System.out.println("感谢使用,再见!");
                    scanner.close();
                    return;
                default:
                    System.out.println("无效的选择,请重新输入。");
            }
        }
    }
    private static void listUsers() {
        String sql = "SELECT id, username, email FROM users";
        try (Connection conn = DBUtil.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            System.out.println("\n--- 用户列表 ---");
            System.out.println("ID\tUsername\tEmail");
            System.out.println("----------------------------------");
            while (rs.next()) {
                System.out.println(rs.getInt("id") + "\t" + rs.getString("username") + "\t\t" + rs.getString("email"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    private static void addUser(Scanner scanner) {
        System.out.print("输入用户名: ");
        String username = scanner.nextLine();
        System.out.print("输入密码: ");
        String password = scanner.nextLine();
        System.out.print("输入邮箱: ");
        String email = scanner.nextLine();
        String sql = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, username);
            pstmt.setString(2, password);
            pstmt.setString(3, email);
            pstmt.executeUpdate();
            System.out.println("用户添加成功!");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    private static void updateUser(Scanner scanner) {
        System.out.print("输入要更新的用户ID: ");
        int id = scanner.nextInt();
        scanner.nextLine(); // 消耗换行符
        System.out.print("输入新邮箱: ");
        String newEmail = scanner.nextLine();
        String sql = "UPDATE users SET email = ? WHERE id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, newEmail);
            pstmt.setInt(2, id);
            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                System.out.println("用户信息更新成功!");
            } else {
                System.out.println("未找到ID为 " + id + " 的用户。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    private static void deleteUser(Scanner scanner) {
        System.out.print("输入要删除的用户ID: ");
        int id = scanner.nextInt();
        String sql = "DELETE FROM users WHERE id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, id);
            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                System.out.println("用户删除成功!");
            } else {
                System.out.println("未找到ID为 " + id + " 的用户。");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

总结与进阶

  • 核心: JDBC 是 Java 连接数据库的标准 API,其流程是固定的:加载驱动 -> 获取连接 -> 创建语句 -> 执行 SQL -> 处理结果 -> 关闭资源。
  • 安全: 永远不要在 Java 代码中拼接 SQL 字符串来执行用户输入的数据,必须使用 PreparedStatement 来防止 SQL 注入。
  • 简洁: 优先使用 try-with-resources 来管理数据库资源,它能避免资源泄漏,使代码更简洁、更健壮。
  • 进阶:
    • 连接池: 在实际生产环境中,频繁地创建和关闭连接是非常消耗性能的,应该使用数据库连接池,如 HikariCP (目前性能最佳)、C3P0、Druid 等,它们可以复用连接,大大提高应用性能。
    • ORM 框架: 对于复杂的业务应用,通常会使用 ORM (Object-Relational Mapping) 框架,如 MyBatisHibernate,它们将数据库表映射为 Java 对象,让你可以用面向对象的方式操作数据库,从而简化开发,提高代码可维护性。

希望这份详尽的教程能帮助你顺利掌握 Java 与 MySQL 的交互!

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