You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java多个类中复用同一个MySQL连接 避免重复创建连接

Java多类共用MySQL连接的实现方案

核心问题解答

你提到的「统一创建连接再传递给其他类」的方案完全可行,传递逻辑和普通参数传递没有区别,除此之外还有更工程化的实现方式,下面是具体的实现思路和代码示例。

推荐实现方案

方案1:单例数据库工具类(最常用)

把数据库配置、连接创建、资源关闭的逻辑都封装到单独的工具类中,全局只维护一个可复用的连接实例,所有需要操作数据库的类都直接从这个工具类获取连接即可。
工具类示例代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DBUtil {
    // 数据库配置统一维护,修改时只需要改此处
    private static final String URL = "jdbc:mysql://localhost:3306/grades";
    private static final String DB_USER = "root";
    private static final String DB_PWD = "root";
    // 全局唯一的连接实例
    private static Connection connection;

    // 私有构造方法,禁止外部实例化工具类
    private DBUtil() {}

    // 对外提供获取连接的方法
    public static Connection getConnection() throws SQLException {
        // 仅当连接为空或已关闭时才创建新连接
        if (connection == null || connection.isClosed()) {
            connection = DriverManager.getConnection(URL, DB_USER, DB_PWD);
        }
        return connection;
    }

    // 统一封装资源关闭逻辑,避免资源泄漏
    public static void close(ResultSet rs, PreparedStatement ps) {
        try {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            // 全局复用的连接不要在这里关闭,程序退出时统一关闭即可
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

改造后的LoginVerify类连接使用逻辑:

// 原来的创建连接代码替换为这一行即可
Connection connection = DBUtil.getConnection();

所有其他需要操作数据库的类都可以用同样的方式获取连接,不需要重复写配置和连接创建逻辑。

方案2:构造方法/参数传递

就是你提到的思路,在程序入口处统一创建连接,实例化业务类时把连接作为参数传入构造方法,业务类将连接保存为成员变量后直接使用。示例逻辑:

// 程序入口处创建连接
Connection globalConn = DBUtil.getConnection();
// 传递给各个业务类
new LoginVerify(globalConn);
new UserMain(user, name, password, globalConn);

这种方式的耦合度更低,也方便后续做单元测试时传入模拟连接。

注意事项

  • 上面的单连接方案适合桌面端这类低并发场景,如果是高并发的Web项目,建议使用HikariCP等数据库连接池管理多个可复用的连接,性能和稳定性更好。
  • 不要频繁开启/关闭连接,复用同一个连接即可,程序退出时再统一关闭连接。
  • 如果需要做事务控制,要先执行connection.setAutoCommit(false)关闭自动提交,所有操作完成后手动调用commit()提交,出现异常时调用rollback()回滚。

原有代码优化建议

你提供的代码中同一个PreparedStatement执行了两次executeQuery(),属于不必要的数据库请求,直接复用第一次查询的结果即可:

ResultSet rs = statement.executeQuery();
if (rs.next()) {
    String name = rs.getString("user_name");
    System.out.println(name);
    new UserMain(user, name, password, null);
} else {
    JLabel l = new JLabel("Username or password incorrect, please try again.");
    l.setFont(new Font("Times New Roman", Font.PLAIN, 15));
    l.setHorizontalAlignment(SwingConstants.CENTER);
    JOptionPane.showMessageDialog(null, l, "ERROR", JOptionPane.PLAIN_MESSAGE);
    new LoginVerify();
}

内容的提问来源于stack exchange,提问作者leah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 08:30:05