求助:Java Swing点击保存按钮误提示‘Record Already Exist’问题
遇到该问题已3天,仍未找到解决方案。点击保存按钮后,明明数据库中不存在对应记录,却弹出‘Record Already Exist’提示。以下是按钮点击事件的代码:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: labelA.setForeground(Color.black); labelB.setForeground(Color.black); jLabel3.setForeground(Color.black); int check=0; try { check = search(textUserId.getText(), textFName.getText()); } catch (SQLException ex) { // Logger.getLogger(frameRegister.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException ex) { //Logger.getLogger(frameRegister.class.getName()).log(Level.SEVERE, null, ex); } if(check==1){ try { if(textPassword.getText() == null ? "" == null : textPassword.getText().equals("")){ JOptionPane.showMessageDialog(null, "First Name and Last must contain value","System Message", JOptionPane.INFORMATION_MESSAGE); textUserAddress.setText(null); textUserId.setText(null); textFName.setText(null); textLName.setText(null); textAge.setText(null); textUBirth.setText(null); textContactNum.setText(null); textPassword.setText(null); textEmailAdd.setText(null); textMaritalStatus.setText(null); textUserOccupation.setText(null); jLabel3.setForeground(Color.red); } if((textUserId.getText() == null ? "" == null : textUserId.getText().equals("")) || (textFName.getText() == null ? "" == null : textFName.getText().equals(""))){ JOptionPane.showMessageDialog(null, "ID and Name is Required","System Message", JOptionPane.ERROR_MESSAGE); labelB.setForeground(Color.red); labelA.setForeground(Color.red); } else{ st.executeUpdate("Insert into info(" + "id,firstname,lastname,age,dateofbirth,marital_status,address,occupation,contact_no,email_add," + "password" + ") VALUES ('" + textUserId.getText() + "','" + textFName.getText() + "','" + textLName.getText() + "','" + textAge.getText() + "','" + textUBirth.getText() + "','" + textMaritalStatus.getText() + "','" + textUserAddress.getText() + "','" + textUserOccupation.getText() + "','" + textContactNum.getText() + "','" + textPassword.getText() + "')"); JOptionPane.showMessageDialog(null, "Record Created", "System Message",JOptionPane.INFORMATION_MESSAGE); frameMain.this.setVisible(false); textUserId.setText(""); frameMain fm= new frameMain(); fm.show(); } } catch (SQLException ex) { // Logger.getLogger(frameMain.class.getName()).log(Level.SEVERE, null, ex); JOptionPane.showMessageDialog(null, "Record Already Exist","System Message", JOptionPane.ERROR_MESSAGE); textUserAddress.setText(null); textUserId.setText(null); textFName.setText(null); textLName.setText(null); textAge.setText(null); textUBirth.setText(null); textContactNum.setText(null); textLName.setText(null); textPassword.setText(null); textMaritalStatus.setText(null); textUserOccupation.setText(null); textEmailAdd.setText(null); } } }
问题根源及解决方案
1. 直接触发异常的原因:SQL字段与参数数量不匹配
Insert语句中声明了11个字段(id,firstname,lastname,age,dateofbirth,marital_status,address,occupation,contact_no,email_add,password),但VALUES里只传入了10个参数,缺少email_add对应的textEmailAdd.getText(),这会直接导致SQL语法错误,触发SQLException,被catch块误判为“记录已存在”。
修复方法:在VALUES中补充email_add的参数:
st.executeUpdate("Insert into info(" + "id,firstname,lastname,age,dateofbirth,marital_status,address,occupation,contact_no,email_add," + "password" + ") VALUES ('" + textUserId.getText() + "','" + textFName.getText() + "','" + textLName.getText() + "','" + textAge.getText() + "','" + textUBirth.getText() + "','" + textMaritalStatus.getText() + "','" + textUserAddress.getText() + "','" + textUserOccupation.getText() + "','" + textContactNum.getText() + "','" + textEmailAdd.getText() + "','" // 补充这一行 + textPassword.getText() + "')");
2. 所有SQLException被误判为记录重复
当前catch块将所有SQLException都当作“记录已存在”处理,但实际异常可能是语法错误、字段类型不匹配、数据库连接问题等。
修复方法:先打印异常详情,再根据异常类型或信息判断:
catch (SQLException ex) { ex.printStackTrace(); // 控制台打印异常详情,方便排查 // 可以根据SQLState判断是否是主键冲突(比如MySQL的1062) if ("1062".equals(ex.getSQLState())) { JOptionPane.showMessageDialog(null, "Record Already Exist","System Message", JOptionPane.ERROR_MESSAGE); } else { JOptionPane.showMessageDialog(null, "操作失败:" + ex.getMessage(), "System Error", JOptionPane.ERROR_MESSAGE); } // 清空字段代码... }
3. 字符串拼接SQL存在注入风险及语法隐患
直接用字符串拼接用户输入的SQL语句,不仅容易被SQL注入,还会因为输入包含单引号等特殊字符导致语法错误。
修复方法:改用PreparedStatement:
// 替换原有的st.executeUpdate代码 String sql = "INSERT INTO info(id, firstname, lastname, age, dateofbirth, marital_status, address, occupation, contact_no, email_add, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); // conn为你的数据库连接对象 pstmt.setString(1, textUserId.getText().trim()); pstmt.setString(2, textFName.getText().trim()); pstmt.setString(3, textLName.getText().trim()); pstmt.setString(4, textAge.getText().trim()); pstmt.setString(5, textUBirth.getText().trim()); pstmt.setString(6, textMaritalStatus.getText().trim()); pstmt.setString(7, textUserAddress.getText().trim()); pstmt.setString(8, textUserOccupation.getText().trim()); pstmt.setString(9, textContactNum.getText().trim()); pstmt.setString(10, textEmailAdd.getText().trim()); pstmt.setString(11, textPassword.getText().trim()); pstmt.executeUpdate(); pstmt.close();
4. 空值判断逻辑错误且冗余
比如textPassword.getText() == null ? "" == null : textPassword.getText().equals("")中,"" == null永远为false,且提示内容“First Name and Last must contain value”和判断password为空完全不匹配。
修复方法:简化空值判断,并修正提示内容:
// 判断密码为空的逻辑 if (textPassword.getText() == null || textPassword.getText().trim().isEmpty()) { JOptionPane.showMessageDialog(null, "Password is required","System Message", JOptionPane.INFORMATION_MESSAGE); jLabel3.setForeground(Color.red); // 清空字段代码... } // 判断ID和姓名为空的逻辑 if (textUserId.getText() == null || textUserId.getText().trim().isEmpty() || textFName.getText() == null || textFName.getText().trim().isEmpty()) { JOptionPane.showMessageDialog(null, "ID and Name is Required","System Message", JOptionPane.ERROR_MESSAGE); labelB.setForeground(Color.red); labelA.setForeground(Color.red); return; // 终止后续代码执行,避免继续触发其他逻辑 }
5. 验证search方法的正确性
check==1才执行后续插入,但不知道search方法的具体逻辑是否正确。需要确认:
search方法是否正确查询数据库中是否存在相同id的记录- 返回值是否符合预期(比如存在返回1,不存在返回0)
- 可以在
search方法中打印查询SQL和结果,排查是否逻辑错误导致误判记录存在
内容的提问来源于stack exchange,提问作者Ware_Wizard

