健康系统数据库查询患者报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
相关产品推荐
相关产品推荐

