Swing登录报空指针:conexao为null无法调用prepareStatement方法
问题根因
抛出空指针的直接原因是类中声明的Connection conexao仅被赋值为null,全程没有完成数据库连接的初始化,执行conexao.prepareStatement(sql)时调用了空对象的方法,自然触发异常。
除此之外现有代码还有两个会导致登录逻辑完全失效的问题:
- 给SQL参数赋值时两次都使用了索引1,密码值会直接覆盖用户名,查询永远无法匹配到正确的账号密码组合
- 没有做资源释放,也没有在登录成功后关闭当前登录窗口,会造成数据库连接泄漏、窗口冗余。
修复步骤
- 补全数据库连接初始化逻辑,在窗体构造方法中完成连接创建,提前导入对应数据库的JDBC驱动依赖,替换成你自己的数据库配置:
// 数据库连接配置,替换为实际环境参数 private final String DB_DRIVER = "com.mysql.cj.jdbc.Driver"; private final String DB_URL = "jdbc:mysql://localhost:3306/你的业务库名?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"; private final String DB_USER = "数据库账号"; private final String DB_PASSWORD = "数据库密码"; public TelaLogin() { initComponents(); // 初始化数据库连接 try { Class.forName(DB_DRIVER); conexao = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); } catch (Exception e) { JOptionPane.showMessageDialog(null, "数据库连接失败:" + e.getMessage()); } }
- 修正
logar()方法的逻辑错误,增加空判断、修正参数索引、补全资源释放逻辑:
public void logar() { String sql = "select * from usuarios where login=? and senha=?"; // 提前校验连接状态,从源头避免空指针 if (conexao == null) { JOptionPane.showMessageDialog(null, "数据库连接不可用,请检查配置"); return; } try { stm = conexao.prepareStatement(sql); // PreparedStatement参数索引从1开始,用户名对应第一个占位符,密码对应第二个 stm.setString(1, txtUsuario.getText().trim()); stm.setString(2, new String(txtSenha.getPassword()).trim()); rs = stm.executeQuery(); if (rs.next()) { new TelaPrincipal().setVisible(true); // 登录成功后关闭当前登录窗口 this.dispose(); } else { JOptionPane.showMessageDialog(null, "用户名或密码错误"); } } catch (Exception e) { JOptionPane.showMessageDialog(null, "登录校验失败:" + e.getMessage()); e.printStackTrace(); } finally { // 依次关闭结果集、语句对象,避免资源泄漏 try { if (rs != null) rs.close(); if (stm != null) stm.close(); } catch (SQLException e) { e.printStackTrace(); } } }
优化建议
- 不建议把数据库连接逻辑直接写在Swing界面类中,单独封装通用的数据库连接工具类统一管理连接创建、释放逻辑,后续维护成本更低
- 数据库中存储的密码不要用明文,建议加Salt做BCrypt哈希后存储,避免拖库后用户密码泄露
- 异常不要只用
System.out.println输出,生产环境建议接入日志框架持久化异常信息,方便排查问题。
内容的提问来源于stack exchange,提问作者Diego Diego Carvalho
相关产品推荐
相关产品推荐

