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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:35:31