不能调用";java.sql.Connection.prepareStatement(字符串)";因为";“数据库连接”;为空(Mysql连接)

不能调用";java.sql.Connection.prepareStatement(字符串)";因为";“数据库连接”;为空(Mysql连接),java,mysql,Java,Mysql,我收到此错误无法调用“java.sql.Connection.prepareStatement(String)”,因为“dbConnection”为null 位于com.claim.classes.Connection.selectRecordsFromTable(Connection.java:24) 在com.claim.classes.Connection.main(Connection.java:12) 看看我的代码,一切看起来都正常,所以我不确定为什么会出现这个错误。下面是我的连接类和

我收到此错误无法调用“java.sql.Connection.prepareStatement(String)”,因为“dbConnection”为null

位于com.claim.classes.Connection.selectRecordsFromTable(Connection.java:24) 在com.claim.classes.Connection.main(Connection.java:12)

看看我的代码,一切看起来都正常,所以我不确定为什么会出现这个错误。下面是我的连接类和DbConnection类的代码

Connection.java

    package com.claim.classes;

        import java.sql.PreparedStatement;
        import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Connection {

    
 public static void main(String args[])throws Exception{  
 selectRecordsFromTable();
 } 
 
 private static void selectRecordsFromTable() throws SQLException {

 Connection dbConnection = null;
 PreparedStatement preparedStatement = null;

 String selectSQL = "SELECT * FROM USER WHERE id = ?";

 try {
 dbConnection = (Connection) DbConnection.getConnection();
 preparedStatement = ((java.sql.Connection) dbConnection).prepareStatement(selectSQL);
 preparedStatement.setInt(1, 16);

 // execute select SQL statement
 ResultSet rs = preparedStatement.executeQuery();

 while (rs.next()) {

   int id  = rs.getInt("id");          
          String email = rs.getString("email");
          String fname = rs.getString("first_name");
          String lname = rs.getString("lanst_name");

          //Display values
          System.out.print("\nID: " + id +"\nEmail: " + email+ "\nfirst name: " + fname+"\nlast Name: " + lname);          
       
 }

 } catch (SQLException e) {

 System.out.println(e.getMessage());

 } finally {

 if (preparedStatement != null) {
 preparedStatement.close();
 }

 if (dbConnection != null) {
 ((Statement) dbConnection).close();
 }

 }

 }
}
package com.claim.classes;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DbConnection{

// public Connection conn;
//static reference to itself
    private static DbConnection instance = new DbConnection();    
    public static final String URL = "jdbc:mysql://localhost:3306/root";
    public static final String USER = "root";
    public static final String PASSWORD = "root";
    public static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver"; 
     
    //private constructor
    private DbConnection() {
        try {
            Class.forName(DRIVER_CLASS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
     
    private Connection createConnection() {
        Connection connection = null;
        try {                  
            connection = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("Connected to Database.");
        } catch (SQLException e) {
            System.out.println("ERROR: Unable to Connect to Database.");
        }
        return connection;
    }   
     
    public static Connection getConnection() {
        return instance.createConnection();
    }
 
}
DbConnection.java

    package com.claim.classes;

        import java.sql.PreparedStatement;
        import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Connection {

    
 public static void main(String args[])throws Exception{  
 selectRecordsFromTable();
 } 
 
 private static void selectRecordsFromTable() throws SQLException {

 Connection dbConnection = null;
 PreparedStatement preparedStatement = null;

 String selectSQL = "SELECT * FROM USER WHERE id = ?";

 try {
 dbConnection = (Connection) DbConnection.getConnection();
 preparedStatement = ((java.sql.Connection) dbConnection).prepareStatement(selectSQL);
 preparedStatement.setInt(1, 16);

 // execute select SQL statement
 ResultSet rs = preparedStatement.executeQuery();

 while (rs.next()) {

   int id  = rs.getInt("id");          
          String email = rs.getString("email");
          String fname = rs.getString("first_name");
          String lname = rs.getString("lanst_name");

          //Display values
          System.out.print("\nID: " + id +"\nEmail: " + email+ "\nfirst name: " + fname+"\nlast Name: " + lname);          
       
 }

 } catch (SQLException e) {

 System.out.println(e.getMessage());

 } finally {

 if (preparedStatement != null) {
 preparedStatement.close();
 }

 if (dbConnection != null) {
 ((Statement) dbConnection).close();
 }

 }

 }
}
package com.claim.classes;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DbConnection{

// public Connection conn;
//static reference to itself
    private static DbConnection instance = new DbConnection();    
    public static final String URL = "jdbc:mysql://localhost:3306/root";
    public static final String USER = "root";
    public static final String PASSWORD = "root";
    public static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver"; 
     
    //private constructor
    private DbConnection() {
        try {
            Class.forName(DRIVER_CLASS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
     
    private Connection createConnection() {
        Connection connection = null;
        try {                  
            connection = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("Connected to Database.");
        } catch (SQLException e) {
            System.out.println("ERROR: Unable to Connect to Database.");
        }
        return connection;
    }   
     
    public static Connection getConnection() {
        return instance.createConnection();
    }
 
}
这里有一个相关的问题,但那个人和我有不同的问题。谢谢你的帮助:)

你有可怕的异常处理,这是这个问题的根源

处理异常的最佳方法是向前抛出异常,特别是如果异常是该方法显然不会基于其实现而仅基于其规范(因此,它的名称、参数类型和javadoc)抛出的类型。在名为
DbConnection
的类中,名为
createConnection
的方法显然应该声明为
抛出SQLException
。因此,修复createConnection方法;应该是:

private Connection createConnection() throws SQLException {
    Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
    System.out.println("Connected to Database.");
    return connection;
}
注意这是多么干净

如果这是不可能的(可能是因为您正在重写一个方法,因此无法添加任何已检查的异常,或者该异常是由于实现细节引起的,不应公开),那么下一个最好的方法是将其作为不同的异常重新播放:

private Connection createConnection() {
    try {
        Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
        System.out.println("Connected to Database.");
        return connection;
    } catch (SQLException e) {
        throw new RuntimeException("Cannot connect to database", e);
    }
}
清楚地说,这是一个糟糕的设计这里,这个方法应该声明为抛出SQLException,它是与DBs交互的基本部分

你所做的是非常非常糟糕的:

首先,它导致了这个问题。主要问题有两方面:

  • 你抛出了很多有用的信息。
    e
    对象具有堆栈跟踪、类型、消息、原因等。通过捕获它,然后将一些内容打印到syserr并继续,您已经将所有有用的信息扔进了垃圾箱

  • 通过继续代码,您的应用程序现在处于一种您从未预料到的状态(在本例中,
    Connection;
    为null,因此返回null。这将导致两个子问题:

  • 2a.实际问题现在发生在一个不相关的地方:问题是您的“连接到DB”调用失败,但由于您的异常处理程序,现在在与此无关的行(即尝试使用null引用的行)上出现问题

    2b.“堆栈跟踪爆炸”-因为代码仍在继续,但应用程序处于您意想不到的状态,显然应用程序很快就会抛出某种异常。如果您所有的异常处理代码都是这样,那么这也会被吞没,并导致一些
    系统。out
    流量,这种情况还会继续下去。ef影响是1个问题导致100个堆栈跟踪转储到sysout,并且除了第一个之外,它们都是完全不相关的

    最后一点发生在你身上。下面是一条简单的规则:


    除非您将实际处理异常或从catch块中重新调用异常,否则决不能捕获异常。System.err不能在其中调用

    您将类命名为
    连接
    。不要这样做。您想要的是
    java.sql.Connection
    而不是
    com.claim.classes.Connection
    和在此基础上,您的代码很难遵循。