杰瑞科技汇

Java MySQL增删改查如何实现?

我们将使用 JDBC (Java Database Connectivity),这是 Java 官方提供的用于执行 SQL 语句的 API,为了简化数据库连接管理,我们会引入一个流行的数据库连接池工具 HikariCP

Java MySQL增删改查如何实现?-图1
(图片来源网络,侵删)

第一步:环境准备

在开始编码之前,请确保你已经准备好以下环境:

  1. Java 开发环境: JDK 8 或更高版本。
  2. MySQL 数据库: 安装并运行 MySQL 服务。
  3. MySQL 驱动: JDBC 驱动程序,用于 Java 连接 MySQL,你可以从 Maven 中央仓库 下载。
  4. IDE: 如 IntelliJ IDEA, Eclipse 等。

第二步:创建数据库和表

在 MySQL 中创建一个测试数据库和一张 users 表。

-- 创建数据库
CREATE DATABASE javadb;
-- 使用数据库
USE javadb;
-- 创建 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);

第三步:项目配置 (Maven)

如果你使用 Maven 来管理项目,请在 pom.xml 文件中添加 MySQL 驱动和 HikariCP 的依赖。

<dependencies>
    <!-- MySQL JDBC 驱动 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version> <!-- 使用你需要的版本 -->
    </dependency>
    <!-- HikariCP 连接池 -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>5.0.1</version> <!-- 使用你需要的版本 -->
    </dependency>
</dependencies>

第四步:创建数据库连接工具类

这是一个最佳实践,我们将数据库连接的创建和管理封装在一个工具类中,使用 HikariCP 连接池来提高性能和稳定性。

Java MySQL增删改查如何实现?-图2
(图片来源网络,侵删)

DBUtil.java

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class DBUtil {
    // 使用 HikariCP 创建数据源
    private static HikariDataSource dataSource;
    static {
        HikariConfig config = new HikariConfig();
        // JDBC URL 格式: jdbc:mysql://[主机名]:[端口]/[数据库名]?[参数]
        config.setJdbcUrl("jdbc:mysql://localhost:3306/javadb?useSSL=false&serverTimezone=UTC");
        config.setUsername("root"); // 你的 MySQL 用户名
        config.setPassword("your_password"); // 你的 MySQL 密码
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
        // 连接池配置 (可选,但推荐)
        config.setMaximumPoolSize(10); // 最大连接数
        config.setMinimumIdle(5);      // 最小空闲连接数
        config.setConnectionTimeout(30000); // 连接超时时间 (毫秒)
        config.setIdleTimeout(600000); // 空闲超时时间 (毫秒)
        config.setMaxLifetime(1800000); // 连接最大存活时间 (毫秒)
        dataSource = new HikariDataSource(config);
    }
    /**
     * 从连接池获取一个数据库连接
     * @return Connection 对象
     * @throws SQLException 如果获取连接失败
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    /**
     * 关闭 Connection (实际上是将连接放回连接池)
     * @param connection 要关闭的连接
     */
    public static void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

第五步:实现增、删、改、查 操作

我们创建一个 UserDAO (Data Access Object) 类来封装所有的数据库操作。

UserDAO.java

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class UserDAO {
    // 1. 查询所有用户 (Read - 查询)
    public List<User> getAllUsers() {
        List<User> users = new ArrayList<>();
        String sql = "SELECT id, name, email, age FROM users";
        // try-with-resources 语句确保资源自动关闭
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String email = rs.getString("email");
                int age = rs.getInt("age");
                users.add(new User(id, name, email, age));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return users;
    }
    // 2. 根据 ID 查询用户 (Read - 查询)
    public User getUserById(int id) {
        String sql = "SELECT id, name, email, age FROM users WHERE id = ?";
        User user = null;
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            // 设置 SQL 语句中的参数
            pstmt.setInt(1, id);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    String name = rs.getString("name");
                    String email = rs.getString("email");
                    int age = rs.getInt("age");
                    user = new User(id, name, email, age);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return user;
    }
    // 3. 添加用户 (Create - 新增)
    public boolean addUser(User user) {
        String sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, user.getName());
            pstmt.setString(2, user.getEmail());
            pstmt.setInt(3, user.getAge());
            // executeUpdate() 返回受影响的行数
            int affectedRows = pstmt.executeUpdate();
            return affectedRows > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }
    // 4. 更新用户 (Update - 修改)
    public boolean updateUser(User user) {
        String sql = "UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?";
        try (Connection conn = DBUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, user.getName());
            pstmt.setString(2, user.getEmail());
            pstmt.setInt(3, user.getAge());
            pstmt.setInt(4, user.getId());
            int affectedRows = pstmt.executeUpdate();
            return affectedRows > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }
    // 5. 删除用户 (Delete - 删除)
    public boolean deleteUser(int id) {
        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();
            return affectedRows > 0;
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }
}

第六步:创建实体类

为了方便操作数据,我们创建一个 User 实体类来映射数据库中的 users 表。

Java MySQL增删改查如何实现?-图3
(图片来源网络,侵删)

User.java

public class User {
    private int id;
    private String name;
    private String email;
    private int age;
    // 构造方法
    public User() {}
    public User(int id, String name, String email, int age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }
    // Getter 和 Setter 方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

第七步:测试

我们创建一个 Main 类来测试我们实现的 CRUD 功能。

Main.java

import java.util.List;
public class Main {
    public static void main(String[] args) {
        UserDAO userDAO = new UserDAO();
        // 1. 查询并打印所有用户
        System.out.println("--- 查询所有用户 ---");
        List<User> allUsers = userDAO.getAllUsers();
        allUsers.forEach(System.out::println);
        // 2. 添加一个新用户
        System.out.println("\n--- 添加新用户 ---");
        User newUser = new User(0, "赵六", "zhaoliu@example.com", 35);
        boolean isAdded = userDAO.addUser(newUser);
        if (isAdded) {
            System.out.println("用户添加成功!");
            // 添加成功后重新查询以确认
            allUsers = userDAO.getAllUsers();
            allUsers.forEach(System.out::println);
        }
        // 3. 更新用户信息
        System.out.println("\n--- 更新用户信息 ---");
        if (!allUsers.isEmpty()) {
            User userToUpdate = allUsers.get(0); // 获取第一个用户进行更新
            userToUpdate.setAge(26);
            userToUpdate.setEmail("zhangsan_new@example.com");
            boolean isUpdated = userDAO.updateUser(userToUpdate);
            if (isUpdated) {
                System.out.println("用户更新成功!");
                allUsers = userDAO.getAllUsers();
                allUsers.forEach(System.out::println);
            }
        }
        // 4. 根据 ID 查询用户
        System.out.println("\n--- 根据 ID 查询用户 ---");
        if (!allUsers.isEmpty()) {
            int userIdToFind = allUsers.get(0).getId();
            User foundUser = userDAO.getUserById(userIdToFind);
            System.out.println("查找到的用户: " + foundUser);
        }
        // 5. 删除用户
        System.out.println("\n--- 删除用户 ---");
        if (!allUsers.isEmpty()) {
            // 删除最后一个添加的用户 (赵六)
            int userIdToDelete = newUser.getId();
            boolean isDeleted = userDAO.deleteUser(userIdToDelete);
            if (isDeleted) {
                System.out.println("用户删除成功!");
                allUsers = userDAO.getAllUsers();
                allUsers.forEach(System.out::println);
            }
        }
    }
}

运行结果

运行 Main.java,你将在控制台看到类似以下的输出(ID 和顺序可能略有不同):

--- 查询所有用户 ---
User{id=1, name='张三', email='zhangsan@example.com', age=25}
User{id=2, name='李四', email='lisi@example.com', age=30}
User{id=3, name='王五', email='wangwu@example.com', age=28}
--- 添加新用户 ---
用户添加成功!
User{id=1, name='张三', email='zhangsan@example.com', age=25}
User{id=2, name='李四', email='lisi@example.com', age=30}
User{id=3, name='王五', email='wangwu@example.com', age=28}
User{id=4, name='赵六', email='zhaoliu@example.com', age=35}
--- 更新用户信息 ---
用户更新成功!
User{id=1, name='张三', email='zhangsan_new@example.com', age=26}
User{id=2, name='李四', email='lisi@example.com', age=30}
User{id=3, name='王五', email='wangwu@example.com', age=28}
User{id=4, name='赵六', email='zhaoliu@example.com', age=35}
--- 根据 ID 查询用户 ---
查找到的用户: User{id=1, name='张三', email='zhangsan_new@example.com', age=26}
--- 删除用户 ---
用户删除成功!
User{id=1, name='张三', email='zhangsan_new@example.com', age=26}
User{id=2, name='李四', email='lisi@example.com', age=30}
User{id=3, name='王五', email='wangwu@example.com', age=28}

总结与最佳实践

  1. 使用 PreparedStatement: 始终使用 PreparedStatement 来执行 SQL 语句,它可以有效防止 SQL 注入攻击,并且对于需要重复执行的 SQL 语句,性能更高。
  2. 使用 try-with-resources: Java 7 引入了 try-with-resources 语句,它能自动实现 Closeable 资源(如 Connection, PreparedStatement, ResultSet)的关闭,即使在 try 块中发生异常,也能确保资源被正确释放,避免了资源泄漏。
  3. 连接池: 在实际生产环境中,绝对不要每次操作都创建和销毁连接,使用 HikariCP 这样的连接池可以复用数据库连接,极大地提升性能和稳定性。
  4. DAO 模式: 将数据库操作逻辑与业务逻辑分离(UserDAO 负责 CRUD,Main 负责业务流程),使代码结构更清晰,更易于维护和测试。
  5. 异常处理: 对数据库操作可能抛出的 SQLException 进行适当的处理(如打印日志、抛出自定义异常等),不要简单地忽略它。
分享:
扫描分享到社交APP
上一篇
下一篇