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

JavaFX租车系统JDBC连接空指针错误修复咨询

修复JDBC中"connection is null"导致无法调用prepareStatement的问题

这个错误的核心原因是DbConnection.getConnection()返回了null,说明数据库连接初始化或获取过程中出现了异常,但现有代码没有及时暴露问题,最终导致调用prepareStatement时触发空指针异常。以下是具体修复步骤:


1. 排查数据库连接参数正确性

首先确认JDBC连接的核心参数是否匹配你的环境:

  • 检查URL中的数据库名Supermarket是否在本地MySQL服务器中真实存在(你的系统是租车系统,可能数据库名应为car_rental之类的名称,需核对)。
  • 确认MySQL服务在localhost:3306正常运行,用户名root和密码Xhq8nc3mcj拥有目标数据库的访问权限。

2. 重构DbConnection类的连接管理逻辑

原代码的静态连接设计和异常处理存在漏洞,导致连接失败时仅记录日志但返回null连接。修改后的代码如下:

package lk.ijse.carrentalsystem.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DbConnection {
    private static DbConnection dbConnection;
    private Connection connection; // 将静态连接改为实例成员,避免单例模式下的静态变量风险

    private DbConnection() throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/Supermarket", "root", "Xhq8nc3mcj");
    }

    public static DbConnection getInstance() throws SQLException, ClassNotFoundException {
        if (dbConnection == null) {
            dbConnection = new DbConnection();
        }
        return dbConnection;
    }

    public Connection getConnection() {
        // 检查连接是否有效,失效则重新建立
        try {
            if (connection == null || connection.isClosed()) {
                connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/Supermarket", "root", "Xhq8nc3mcj");
            }
        } catch (SQLException e) {
            Logger.getLogger(DbConnection.class.getName()).log(Level.SEVERE, null, e);
            throw new RuntimeException("数据库连接重建失败", e);
        }
        return connection;
    }
}

修改说明:

  • 移除静态connection,改为单例实例的成员变量,避免多线程场景下的潜在问题。
  • 构造函数抛出异常,强制调用者感知连接初始化失败,而非默默返回null。
  • 在getConnection()中增加连接有效性检查,若连接关闭或为空则自动重建。

3. 修正CustomerDaoImpl的连接使用逻辑

原代码未确保单例初始化,且未处理连接为null的情况,修改后代码如下:

import lk.ijse.carrentalsystem.dao.custom.CustomerDao;
import lk.ijse.carrentalsystem.db.DbConnection;
import lk.ijse.carrentalsystem.entity.CustomerEntity;

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

public class CustomerDaoImpl implements CustomerDao {

    @Override
    public boolean addCustomer(CustomerEntity entity) throws Exception {
        String sql = "INSERT INTO customer (custTitle, custName, custNic, address, mobile) VALUES (?, ?, ?, ?, ?)";

        // 先初始化单例实例,确保连接已建立
        DbConnection.getInstance();
        
        try (Connection connection = DbConnection.getInstance().getConnection()) {
            // 提前检查连接是否有效,避免后续空指针
            if (connection == null) {
                throw new SQLException("无法获取有效数据库连接");
            }
            
            try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                preparedStatement.setString(1, entity.getCustTitle());
                preparedStatement.setString(2, entity.getCustName());
                preparedStatement.setString(3, entity.getCustNic());
                preparedStatement.setString(4, entity.getAddress());
                preparedStatement.setString(5, entity.getMobile());

                int rowsAffected = preparedStatement.executeUpdate();
                return rowsAffected > 0;

            } catch (SQLException e) {
                e.printStackTrace();
                throw e; // 抛出异常让上层业务逻辑处理,而非静默返回false
            }
        }
    }
}

修改说明:

  • 先调用DbConnection.getInstance()确保单例初始化,避免直接获取连接时未完成初始化。
  • 增加连接非空检查,提前抛出异常,避免后续调用prepareStatement触发空指针。
  • 捕获SQL异常后重新抛出,让上层感知操作失败,而非仅打印日志后返回false。

额外优化建议

  • 不要硬编码数据库参数,将URL、用户名、密码存入配置文件(如db.properties),便于维护。
  • 替换JDK默认Logger为SLF4J+Logback等更灵活的日志框架,提升日志可读性。
  • 确认MySQL驱动依赖已正确添加到项目中,版本需与MySQL服务器版本匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 17:17:28