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

健康系统数据库查询患者报java.lang.NullPointerException问题排查

解决你的java.lang.NullPointerException问题及健康系统查询功能优化

兄弟,你的空指针异常根源非常明确——你根本没有初始化数据库连接conn就直接调用了conn.createStatement(),和用姓名当查询条件没关系,咱们一步步来梳理问题和修复方案:

1. 空指针异常的直接原因

你声明了Connection conn = null;,但之后完全没有写建立实际数据库连接的代码(比如通过DriverManager.getConnection()获取连接),就直接调用conn.createStatement(),这必然会抛出空指针异常,因为conn此时还是null。

2. 代码里的其他隐性问题

  • SQL语句与结果集不匹配:你写的SELECT fname, lname FROM Services只查询了两个字段,但结果集里却尝试获取paitinet_id(还有拼写错误,应该是patient_id)和service_type,这些字段根本不在你查询的列里;而且从需求看,你应该关联患者表和服务表,而不是直接查Services表。
  • 未使用输入的查询条件:你的代码完全没用到输入框里的患者姓名,等于做了全量查询,和你“按姓名查询患者”的需求不符。
  • 资源关闭不规范:当前的资源关闭逻辑不够严谨,容易导致连接泄漏,建议用try-with-resources语法自动管理资源。
  • 拼写错误:serachPatient方法名少写了一个e(应该是searchPatient),paitinet_id拼写错误,这些小问题也会给后续维护埋坑。

3. 修正后的完整代码示例

下面是补全连接逻辑、结合输入框姓名查询、修正所有问题后的代码:

// 先确保你已经通过FXML或者代码获取了输入框的引用,比如:
@FXML
private TextField nameInput;

public void searchPatient() throws ClassNotFoundException, SQLException {
    // 替换成你自己的数据库连接参数
    String dbUrl = "jdbc:mysql://localhost:3306/你的健康系统数据库名?useSSL=false&serverTimezone=UTC";
    String dbUser = "你的数据库用户名";
    String dbPassword = "你的数据库密码";

    // 使用try-with-resources自动关闭连接、语句、结果集,无需手动close
    try (Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);
         Statement stmt = conn.createStatement()) {

        // MySQL 8.0+建议用这个驱动类,旧的com.mysql.jdbc.Driver已经废弃
        Class.forName("com.mysql.cj.jdbc.Driver");
        System.out.println("数据库连接成功,准备执行查询...");

        // 获取输入框的患者姓名,做非空处理
        String patientName = nameInput.getText().trim();
        if (patientName.isEmpty()) {
            System.out.println("请输入患者姓名再查询");
            return;
        }

        // 关联患者表和服务表,按姓名模糊查询(如果需要精确匹配就把LIKE换成=)
        String sql = "SELECT p.patient_id, p.fname, p.lname, s.service_type " +
                     "FROM Patients p " +
                     "JOIN Services s ON p.patient_id = s.patient_id " +
                     "WHERE CONCAT(p.fname, ' ', p.lname) LIKE '%" + patientName + "%'";

        try (ResultSet rs = stmt.executeQuery(sql)) {
            // 检查是否查到结果
            if (!rs.isBeforeFirst()) {
                System.out.println("未找到姓名包含「" + patientName + "」的患者");
                return;
            }

            while (rs.next()) {
                int id = rs.getInt("patient_id");
                String firstName = rs.getString("fname");
                String lastName = rs.getString("lname");
                String serviceType = rs.getString("service_type");

                // 格式化输出,可读性更好
                System.out.println("------------------------");
                System.out.println("患者ID: " + id);
                System.out.println("患者姓名: " + firstName + " " + lastName);
                System.out.println("所需服务类型: " + serviceType);
            }
        }
    } catch (SQLException se) {
        se.printStackTrace();
        System.err.println("数据库操作出错,请检查连接参数或SQL语句");
    } catch (Exception e) {
        e.printStackTrace();
        System.err.println("系统运行异常");
    }
}

// 搜索按钮事件处理
search.setOnAction(e -> {
    try {
        searchPatient(); // 修正方法名拼写
    } catch (ClassNotFoundException | SQLException e1) {
        e1.printStackTrace();
    }
});

4. 生产环境额外建议

  • 避免SQL注入:上面的示例用了字符串拼接SQL,存在SQL注入风险,生产环境建议用PreparedStatement,示例如下:
String sql = "SELECT p.patient_id, p.fname, p.lname, s.service_type " +
             "FROM Patients p " +
             "JOIN Services s ON p.patient_id = s.patient_id " +
             "WHERE CONCAT(p.fname, ' ', p.lname) LIKE ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setString(1, "%" + patientName + "%");
    try (ResultSet rs = pstmt.executeQuery()) {
        // 处理结果集逻辑不变
    }
}
  • 驱动适配:如果你的MySQL版本是8.0及以上,必须使用com.mysql.cj.jdbc.Driver,同时JDBC URL要加上时区参数serverTimezone=UTC。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:27:59