Java,代码可以工作,但仍然会引发异常

Java,代码可以工作,但仍然会引发异常,java,sql,exception,Java,Sql,Exception,我正在创建一个简单的注册框架,将记录添加到数据库中。它每次运行SQL查询在数据库中添加记录时都会给我一条错误消息,但它仍然会添加记录,因此我的程序停止运行,而不是打开另一个窗口 这是代码的一部分: regButton.addActionListener(new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { //Execute when button is pressed if(

我正在创建一个简单的注册框架,将记录添加到数据库中。它每次运行SQL查询在数据库中添加记录时都会给我一条错误消息,但它仍然会添加记录,因此我的程序停止运行,而不是打开另一个窗口

这是代码的一部分:

regButton.addActionListener(new ActionListener() {

@Override public void actionPerformed( ActionEvent e ) {
   //Execute when button is pressed
   if(   uNameField.getText().equals("")
      || new String(newPassField.getPassword()).equals("")
      || new String(repeatPassField.getPassword()).equals("") ) {
      errorLabel.setForeground(Color.red);
      errorLabel.setText("Some fields are left blank");
   }
   else if( new String(newPassField.getPassword()).equals(
            new String(repeatPassField.getPassword()))){
      Statement stmt;
      ResultSet res;
      try
      {
         //SET USERNAME AND PASSWORD FROM FIELDS TO UPPER CASE
         String username = uNameField.getText().toUpperCase();
         String password = new String(newPassField.getPassword()).toUpperCase();
         //SQL INSERT QUERY
         String sql;
         sql = "INSERT INTO Employees VALUES ('" +username +"','" +password +"');";
         stmt = con.createStatement();
         res = stmt.executeQuery(sql);
         System.out.println("Added to database!");
         con.close();
      }
      catch(SQLException exe) {
         System.out.println("Error creating or running statement: " + e.toString());
         try {
            con.close();
         }
         catch(Exception eex){}
      }
   }
   else {
      errorLabel.setForeground(Color.red);
      errorLabel.setText("Password missmatch");
   }
}
每次注册新员工(用户)时,它都会显示“创建或运行语句时出错:…”,不过,我可以在员工列表中找到新添加的员工

什么可能导致此问题?

您需要使用SQL插入

int rowCount = stmt.executeUpdate(sql);
您需要使用for SQL插入

int rowCount = stmt.executeUpdate(sql);

在讨论您的具体问题之前,请给出一些一般性建议:

Connection con = ...
try {
    // your stuff
}
catch (Exception e) {
  e.printStackTrace();
}
finally {
  try {
    con.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
}
您现在的操作方式不仅吞咽了异常,还避免了打印其堆栈跟踪。和
close
必须执行一次且仅执行一次,无论异常情况如何

如果您使用的是Java 7,这将更容易:

try (Connetion con = ...) {
  // stuff to do
}
catch (Exception e) {
  e.printStackTrace();
}
现在,
最后
中的关闭操作将自动完成


特别是关于您的异常,您可以通过调用
executeQuery
来执行插入。此方法将语句发送到DB,DB会正确执行该语句,但返回给JDBC的响应不是ResultSet。这就是它在插入记录后爆炸的地方。由于您处于自动提交模式,因此没有要回滚的事务。教训:始终使用事务

在我们讨论您的具体问题之前,请给出一些一般性建议:

Connection con = ...
try {
    // your stuff
}
catch (Exception e) {
  e.printStackTrace();
}
finally {
  try {
    con.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
}
您现在的操作方式不仅吞咽了异常,还避免了打印其堆栈跟踪。和
close
必须执行一次且仅执行一次,无论异常情况如何

如果您使用的是Java 7,这将更容易:

try (Connetion con = ...) {
  // stuff to do
}
catch (Exception e) {
  e.printStackTrace();
}
现在,
最后
中的关闭操作将自动完成


特别是关于您的异常,您可以通过调用
executeQuery
来执行插入。此方法将语句发送到DB,DB会正确执行该语句,但返回给JDBC的响应不是ResultSet。这就是它在插入记录后爆炸的地方。由于您处于自动提交模式,因此没有要回滚的事务。教训:始终使用事务

我讨厌看到这样编写的代码。你没有问过这件事,我的评论也不能解决你的问题,但我认为有必要说出来

通过将持久性代码放入Swing侦听器方法,您正在为自己制造维护噩梦

一个更好的想法是以一种赋予对象单一责任的方式来思考对象

将您的持久性代码移动到一个单独的类中,您可以自行开发和测试该类。一旦它起作用,给需要它的类一个引用

您的代码将更加模块化,更易于测试,更易于重用,并且不太容易理解


Bob Martin叔叔对这一点和其他值得记住的想法有一个简洁的记忆法:。

我讨厌看到这样写的代码。你没有问过这件事,我的评论也不能解决你的问题,但我认为有必要说出来

通过将持久性代码放入Swing侦听器方法,您正在为自己制造维护噩梦

一个更好的想法是以一种赋予对象单一责任的方式来思考对象

将您的持久性代码移动到一个单独的类中,您可以自行开发和测试该类。一旦它起作用,给需要它的类一个引用

您的代码将更加模块化,更易于测试,更易于重用,并且不太容易理解


鲍勃·马丁叔叔对这一点和其他值得记住的想法有一个简洁的记忆法:。

你为什么不试试事先准备好的陈述

try{
    //SET USERNAME AND PASSWORD FROM FIELDS TO UPPER CASE
     String username = uNameField.getText().toUpperCase();
     String password = new String(newPassField.getPassword()).toUpperCase();
     //SQL INSERT QUERY
     PreparedStatement pstmt = con.prepareStatement("insert into Employees values(?,?)");
     pstmt.setString(1,username);
     pstmt.setString(2,password);

     if(!pstmt.execute())
     {
       //means your code worked correctly
        System.out.println("Inserted successfully");
     }
     else
     {
           System.out.println("Unsuccessfull");
     }
   }
   catch(Exception ex)
   {
      ex.printStackTrace();
   }

你为什么不试试事先准备好的声明呢

try{
    //SET USERNAME AND PASSWORD FROM FIELDS TO UPPER CASE
     String username = uNameField.getText().toUpperCase();
     String password = new String(newPassField.getPassword()).toUpperCase();
     //SQL INSERT QUERY
     PreparedStatement pstmt = con.prepareStatement("insert into Employees values(?,?)");
     pstmt.setString(1,username);
     pstmt.setString(2,password);

     if(!pstmt.execute())
     {
       //means your code worked correctly
        System.out.println("Inserted successfully");
     }
     else
     {
           System.out.println("Unsuccessfull");
     }
   }
   catch(Exception ex)
   {
      ex.printStackTrace();
   }

您可以打印正在吞咽的异常的堆栈跟踪并将其添加到问题中吗?您可以使用变量
exe
打印堆栈跟踪吗?您可以打印正在吞咽的异常的堆栈跟踪并将其添加到问题中吗?您可以使用变量
exe
@Aubin打印堆栈跟踪吗,如果OP可以使用@Aubin当然可以,如果OP可以使用。很可能,这段代码不会维护,但开始学习正确的方法永远不会太早。很可能,这段代码不会维护,但开始学习正确的方法永远不会太早。当我更改它时,我在那一行得到一个错误,上面写着“不兼容的类型,必需的java.sql.ResultSet,find Int当我更改它时,我在那一行得到一个错误,上面写着“不兼容的类型,必需的java.sql.ResultSet,find Int”