java.lang.NullPointerException ... 初始化 JDBC MYSQL 连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21389079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:25:51  来源:igfitidea点击:

java.lang.NullPointerException ... Initializing the JDBC MYSQL connection

javamysqlswing

提问by Adarsh Singhal

Please don't suggest me to use InternalFrame or Dialogs. I can't start the project from beginning. Theme:I'm building a GUI program to display mark-sheet. I've taken 3 JFrames & 1 simple class...

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

Frame1.java

框架1.java

It's having 1 JTextField to enter roll_no. & 2 buttons to feedData in DB & showResult. feedData button calls Frame2 & showResult button calls Frame3.

它有 1 个 JTextField 来输入 roll_no。和 2 个按钮在 DB 和 showResult 中馈送数据。feedData 按钮调用 Frame2,showResult 按钮调用 Frame3。

Frame2.java

框架2.java

For feeding data have several JTextFields & Buttons that transfer content to mySQL DB.

对于馈送数据,有几个 JTextFields & Buttons 将内容传输到 mySQL DB。

Frame3.java

框架3.java

is a result window that fetches content from DB.

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

Support.java

支持.java

Contains static variables & getter-setter methods for them

包含它们的静态变量和 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() is called on pressing save button in Frame2.java . . . If catch block is executing, why println(query) printing NULL

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

采纳答案by Ian McLaird

Based on some of your question tags and responses in the comments to other answers and on the question itself, I'm presuming that somewhere in your code, you intend to call

根据你的一些问题标签和对其他答案的评论中的回答以及问题本身,我假设你的代码中的某个地方,你打算打电话

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

This is not happening before your add()method is called. In order to fix it, I'd recommend this (bulk of code borrowed from Vivek bhatnagar's answer):

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
}

If you're on Java 7, set up like this:

如果您使用的是 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
}

How could I tell what your problem was (general help for NullPointerException)?

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

NullPointerExceptionis only thrown when you try to call a method on a nullvariable (and at a few other specific times, as noted in the API documentation). The easy way to locate a NullPointerExceptionis to look for the line the stack trace indicates, and then look for the dots on the line. There's only two lines in your tryblock that can throw a NullPointerException.

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

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

and

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

So let's look at the dots. The first one will throw when connis null. The second one will throw when stmtis null. In your original code, which you've now edited in response to the other answers, you set the value of queryafter you called conn.createStatement();. Since querywas still null in your catchblock, we know that it hadn't yet been set, and thus it must be the first one, so connis nullat that point in the program.

那么让我们来看看这些点。第一个将在connis时抛出null。第二个将在stmtis时抛出null。在您现在为响应其他答案而编辑的原始代码中,您在query调用conn.createStatement();. 因为query在你还在空catch块,我们知道,它尚未确定,因此它必须是第一位的,所以connnull在程序中这一点。

Furthermore, since the API Documentation for createStatementimplies that it will either return a valid Connectionobject or throw an SQLException, we can be pretty sure that stmtwill never be nullwhen executeUpdateis called.

此外,由于对的createStatement API文档意味着它要么返回一个有效的Connection对象或抛出SQLException,我们可以相当肯定stmt将永远不会被nullexecuteUpdate被调用。

回答by Southpaw Hare

In your try block, you are calling a method that is possible to throw an exception before setting the variable in question:

在您的 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()+")";

Therefore, if your code fails on the conn.createStatement() line, it will enter the catch block without the query variable being initialized.

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

You can fix this simply by switching the order of the statements, or by putting the query line outside and before the try/catch blocks.

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

回答by Vivek

Adding to what @Southpaw answered :

添加@Southpaw回答的内容:

you can use something like this also :

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

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();

Kindly Note its benefits:

请注意它的好处:

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.