Java JFrame Swing ResultSet报错处理及用户名唯一性校验插入实现
Java Swing 账号插入功能的问题修复与优化
原代码存在的核心问题
- ResultSet调用错误:使用
PreparedStatement时,错误调用带SQL参数的executeQuery(sql2),正确做法是调用无参的executeQuery(),因为PreparedStatement已预编译SQL语句。 - 逻辑完全倒置:
res.next()返回true代表用户名已存在,此时应提示占用而非插入;仅当res.next()返回false(无匹配数据)时,才执行插入操作。 - SQL注入风险:直接拼接字符串生成SQL,未使用
PreparedStatement参数绑定,存在安全隐患。 - 资源泄漏:Connection、Statement、PreparedStatement、ResultSet未关闭,会耗尽数据库连接资源。
- 冗余代码:创建了未使用的
Statement stat对象。 - 异常处理不足:仅打印异常,未给用户直观的错误提示。
修正后的完整代码
// TODO add your handling code here: PreparedStatement checkStmt = null; PreparedStatement insertStmt = null; Connection con = null; ResultSet res = null; try { Class.forName("com.mysql.cj.jdbc.Driver"); con = DriverManager.getConnection("jdbc:mysql://localhost:3306/xaramat","root",""); String username = Username_txt.getText().trim(); String password = Password_txt.getText().trim(); String role = this.Role.getSelectedItem().toString(); // 校验用户名是否存在,使用参数绑定避免SQL注入 String checkSql = "SELECT Username FROM admin WHERE Username = ?"; checkStmt = con.prepareStatement(checkSql); checkStmt.setString(1, username); res = checkStmt.executeQuery(); if (!res.next()) { // 用户名未被占用,执行插入 String insertSql = "INSERT INTO admin(Username, Password, Type) VALUES (?, ?, ?)"; insertStmt = con.prepareStatement(insertSql); insertStmt.setString(1, username); insertStmt.setString(2, password); insertStmt.setString(3, role); insertStmt.executeUpdate(); JOptionPane.showMessageDialog(this, "账号添加成功!"); // 清空输入框 Username_txt.setText(""); Password_txt.setText(""); this.Role.setSelectedIndex(0); } else { JOptionPane.showMessageDialog(this, "用户名已被占用,请更换!"); } } catch (ClassNotFoundException e) { JOptionPane.showMessageDialog(this, "数据库驱动加载失败:" + e.getMessage()); } catch (SQLException e) { JOptionPane.showMessageDialog(this, "数据库操作错误:" + e.getMessage()); } finally { // 关闭所有资源,避免泄漏 try { if (res != null) res.close(); if (checkStmt != null) checkStmt.close(); if (insertStmt != null) insertStmt.close(); if (con != null) con.close(); } catch (SQLException e) { e.printStackTrace(); } }
关键优化说明
- 参数绑定:所有SQL操作均使用
PreparedStatement的setString方法绑定参数,彻底避免SQL注入。 - 逻辑修正:通过
!res.next()判断用户名未被占用时才执行插入。 - 资源管理:在
finally块中统一关闭所有数据库资源,确保资源释放。 - 异常细化:分类型捕获异常,并给用户显示具体错误信息,提升体验。
- 代码精简:移除冗余的
Statement对象,变量命名更规范(符合Java命名规范)。
内容的提问来源于stack exchange,提问作者Pay
相关产品推荐
相关产品推荐

