【问题标题】:java.lang.NullPointerException ... Initializing the JDBC MYSQL connectionjava.lang.NullPointerException ... 初始化 JDBC MYSQL 连接
【发布时间】:2014-01-27 18:47:09
【问题描述】:

请不要建议我使用 InternalFrame 或 Dialogs。我无法从头开始项目。 主题:我正在构建一个 GUI 程序来显示标记表。我参加了 3 个 JFrames 和 1 个简单的课程...

Frame1.java

它有 1 个 JTextField 可以输入 roll_no。 & 2 个按钮在 DB & showResult 中提供数据。 feedData 按钮调用 Frame2 和 showResult 按钮调用 Frame3。

Frame2.java

为了提供数据,有几个 JTextFields & Buttons 可以将内容传输到 mySQL DB。

Frame3.java

是一个从数据库中获取内容的结果窗口。

Support.java

包含静态变量和 getter-setter 方法

 .....
 .....//contains in Support.java
     public boolean add() {
    query = "Insert into table1 (enroll,Sname,Fname,sub1,sub2,sub3,sub4,sub5 )values(?,?,?,?,?)";
    try {
        PreparedStatement psmt = conn.prepareStatement(query);
        psmt.setString(1, enroll);
        psmt.setString(2, Sname);
        psmt.setString(3, Fname);
        psmt.setInt(4, sub1);
        psmt.setInt(5, sub2);
        psmt.setInt(6, sub3);
        psmt.setInt(7, sub4);
        psmt.setInt(8, sub5);
        int y = 0;
        y = psmt.executeUpdate();
        if (y == 0) {
            return false;
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

add() 在 Frame2.java 中按下保存按钮时调用。 . .如果 catch 块正在执行,为什么 println(query) 打印 NULL

【问题讨论】:

  • 您遇到了什么异常?我猜它试图创建语句失败。
  • 旁注:使用PreparedStatements,您的代码容易受到 SQL 注入的攻击
  • 如果我不得不猜测,我会说你的问题是你还没有初始化conn
  • 我猜,Ian McLaird... 你说的是 conn = DriverManager.getConnection(url,username,password);
  • 是的。您确定在调用add() 方法之前已将有效的Connection 对象分配给conn?如发布的那样,您的代码没有设置该变量(尽管它可能在您未发布的代码中的其他地方这样做)。您可以发布堆栈跟踪的相关部分吗?

标签: java mysql swing


【解决方案1】:

根据您在 cmets 中对其他答案的一些问题标签和响应以及问题本身,我假设您打算在代码中的某个地方调用

Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, username, password);

在调用 add() 方法之前不会发生这种情况。为了修复它,我建议这样做(从 Vivek bhatnagar 的答案中借用的大量代码):

try {
    conn = DriverManager.getConnection(url, username, password);
    PreparedStatement pstmt = conn.prepareStatement("INSERT INTO `table`
        (pid,tid,rid,tspend,description) VALUE 
        (?,?,?,?,?)");
    pstmt.setString(1, pid );
    pstmt.setString(2, tid);
    pstmt.setString(3, rid);
    pstmt.setInt(4, tspent);
    pstmt.setString(5,des );
    pstmt.executeUpdate();
} catch (Exception e) {
    // whatever you want to do to handle the exception
} finally {
    // close your connection
}

如果您使用的是 Java 7,请按如下方式设置:

try (Connection conn = DriverManager.getConnection(url, username, password)) {
    try (PreparedStatement pstmt = conn.prepareStatement(/*sql here*/)) {
        // Your code here
    } catch (SQLException sqle) {
        // handle exceptions from the statement
    }
} catch (SQLException outerSqlEx) {
    // handle exceptions from connecting
}

我怎么知道你的问题是什么(NullPointerException 的一般帮助)?

NullPointerException 仅在您尝试调用 null 变量上的方法时抛出(以及在其他几个特定时间,如 API 文档中所述)。找到NullPointerException 的简单方法是查找堆栈跟踪指示的行,然后查找行上的点。 try 块中只有两行可以抛出 NullPointerException

Statement stmt = conn.createStatement();
// could be here ----^ 

y = stmt.executeUpdate(query);
// or --^

让我们看看这些点。当connnull 时,第一个将抛出。当stmtnull 时,第二个将抛出。在您现在已针对其他答案进行编辑的原始代码中,您在调用conn.createStatement(); 后设置了query 的值。由于query 在你的catch 块中仍然为空,我们知道它尚未设置,因此它必须是第一个,所以conn 在程序中的那个点是null

此外,由于API Documentation for createStatement 意味着它要么返回一个有效的Connection 对象,要么抛出一个SQLException,我们可以确定stmt 在调用executeUpdate 时永远不会是null

【讨论】:

  • 非常感谢大家...问题是空连接。您给了我满意的解决方案,现在一切正常
【解决方案2】:

在您的 try 块中,您在设置相关变量之前调用可能引发异常的方法

    Statement stmt = conn.createStatement();
    query = "Insert into table1 (enroll,Sname,Fname,sub1,sub2,sub3,sub4,sub5 )values('" + getEnroll() + "','" + getSname() + "','"+getFname()+"',"+getSub1()+","+getSub2()+","+getSub3()+","+getSub4()+","+getSub5()+")";

因此,如果您的代码在 conn.createStatement() 行上失败,它将进入 catch 块,而不会初始化查询变量。

您可以简单地通过切换语句的顺序来解决此问题,或者将查询行放在 try/catch 块之外和之前。

【讨论】:

  • 查询不再为 NULL...但我仍然收到 NullPointerException 并且显然 catch() 正在执行..请帮助..
  • 我的回答没有错。变量“query”在到达设置它的行之前为空,如果事先抛出异常,它将不会到达该行。
  • 是的,我同意你的看法。我已经按照你说的移动了。你能帮我修复它吗,因为它正在执行 catch()
  • 抛出的异常(可能来自 conn.createStatement() 行)是一个完全独立的问题,但如果它也是 NullPointerException,则可能是由于 conn 也为空。您应该更加小心地确保使用值初始化变量,因为在 null 值上调用任何方法都是错误的,这是理所当然的 - 这是荒谬的。
  • 查询字符串一切正常。问题仍然存在仅由于空连接。如何处理。
【解决方案3】:

补充@Southpaw 的回答:

你也可以使用这样的东西:

PreparedStatement pstmt = con.prepareStatement("INSERT INTO `table`
        (pid,tid,rid,tspend,description) VALUE 
        (?,?,?,?,?)");
pstmt.setString(1, pid );
pstmt.setString(2, tid);
pstmt.setString(3, rid);
pstmt.setInt(4, tspent);
pstmt.setString(5,des );
pstmt.executeUpdate();

请注意它的好处:

1."Query is rewritten and compiled by the database server"

If you don't use a prepared statement, the database server will have to parse, and compute an execution plan for the statement each time you run it. If you find that you'll run the same statement multiple times (with different parameters) then its worth preparing the statement once and reusing that prepared statement. If you are querying the database adhoc then there is probably little benefit to this.

2."Protected against SQL injection"

This is an advantage you almost always want hence a good reason to use a PreparedStatement everytime. Its a consequence of having to parameterize the query but it does make running it a lot safer. The only time I can think of that this would not be useful is if you were allowing adhoc database queries; You might simply use the Statement object if you were prototyping the application and its quicker for you, or if the query contains no parameters.

【讨论】:

  • 虽然是真的,但这并不能解决 OP 正在获取的 NullPointerException。
猜你喜欢
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 2017-08-17
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 2017-11-18
相关资源
最近更新 更多