1

我试图使用 jdbc 将值从文本字段插入到 mySql,但我的问题是我在关闭准备好的语句时出现空指针错误。这是我的代码

 private Connection con;
 private Statement stm;
 private ResultSet rs;
 private PreparedStatement ps ;



public void dbConnect(){
    try{
        Class.forName("com.mysql.jdbc.Driver");
        this.con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbTestDrive"
                + "", "root", "password");

    }
    catch(ClassNotFoundException ex){}
    catch(SQLException ex){}
}

 public boolean insert(Member member)throws SQLException{
    this.dbConnect();
    boolean success = false;
    String query = "INSERT INTO try VALUES(?, ?)";
            try {
        this.ps = this.con.prepareStatement(query);
        this.ps.setString(1, member.getMemberId());
        this.ps.setString(2, member.getFirstName());


       int rows = this.ps.executeUpdate();
        if(rows>0){
            success = true;
        }

    } catch (SQLException ex) {
        ex.printStackTrace();
        throw ex;
    } finally{
        this.ps.close(); // this is my line: 56 (im getting null pointer here)
        this.con.close();
    }

    return success;
}

这是堆栈跟踪:

   Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at rtu.tomis.dao.MemberDao.insert(MemberDao.java:56)
at rtu.tomis.gui.AddMemberView.btnSaveActionPerformed(AddMemberView.java:993)
at rtu.tomis.gui.AddMemberView.access$800(AddMemberView.java:21)
at rtu.tomis.gui.AddMemberView$9.actionPerformed(AddMemberView.java:476)

谢谢你的帮助

4

5 回答 5

3

try在该行执行之前或期间,您在块内遇到异常:

this.ps = this.con.prepareStatement(query);

catch块重新抛出异常后,块finally执行。不幸的是,因为psis null,您会得到另一个异常,然后抛出该异常,隐藏原始异常。

您需要更具防御性地编写代码,仅在它们不是时才关闭pscon并捕获调用本身可能引发null的任何异常。close()这将允许您传播try.

您也不应该默默地try忽略dbConnect(). 我怀疑有一个例外是你问题的根源。

于 2012-12-20T04:39:23.857 回答
2

你应该这样写你的代码:

finally{
  if(ps != null)
        try{
            this.ps.close(); 
        }catch(Exception e){
            System.out.println("PreparedStatement close problem");
        }
  if(con != null)
        try{
            this.con.close();
        }catch(Exception e){
            System.out.println("Database Connection close problem");
        }
}

如果由于某些错误而未初始化任何conor ,这将避免空指针异常。ps

您也可以this从所有代码中删除关键字,因为您的方法中没有任何与类变量同名的局部变量,因此不会有任何歧义

于 2012-12-20T04:35:10.927 回答
0

您需要在 finally 子句中检查 null

finally{
  if(ps != null)
        this.ps.close();
   //
}

但潜在的问题可能是当您打开连接时,它失败后将不会初始化您准备好的语句:

this.ps = this.con.prepareStatement(query);

换句话说,在调用之前prepareStatement确保con不为空。您应该更改方法dbConnect并打印异常,这将帮助您解决问题的原因。

 try{
        Class.forName("com.mysql.jdbc.Driver");
        this.con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbTestDrive"
                + "", "root", "password");

    }
    catch(ClassNotFoundException ex){
     ex.printStackTrace();
    }
    catch(SQLException ex){
     ex.printStackTrace();
    }
于 2012-12-20T04:40:31.430 回答
0

您没有在插入方法中获得 Prepared Statement 对象,并且在 null 上调用任何内容都会给您带来 Null 指针异常。

于 2012-12-20T07:14:15.823 回答
0

我确实认为您的 dbConnect() 方法中抛出了一个异常,这就是为什么 jvm 在读取准备好的语句的实例化之前直接读取 finally 的原因。

于 2012-12-20T04:42:19.357 回答