JDBC Unreachable'create statement'statement

问题描述 投票:1回答:3

我当前正在编写一个与SQL数据库通信的程序,在进行查询后,显然必须关闭连接,可以很好地关闭连接,但不能关闭实际的语句本身。是否需要关闭它还是因为它是连接本身的功能而关闭?代码运行得很好,我只是好奇是否需要此语句。这是代码,在returnEmployeeSalary函数结尾处突出显示错误:

public class GroundControlToMajorTom {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        System.out.println(returnEmployeeSalary("ivy"));

    }

    public static String returnEmployeeSalary(String name) throws ClassNotFoundException, SQLException {
        HashMap<String, String> infoHR = connectionInfoHR();

        String query = "SELECT salary FROM employees WHERE first_name = '" + name + "'";

        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection con = DriverManager.getConnection(infoHR.get("url"), infoHR.get("uname"), infoHR.get("pass"));

        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery(query);

        rs.next();
        String id = rs.getString("salary");

        return id;

        st.close(); /////////// ERROR IS HERE /////////////
        con.close();
    }

    public static HashMap<String, String> connectionInfoHR() {
        HashMap<String, String> infoHR = new HashMap();

        infoHR.put("url", "jdbc:mysql://localhost:3306/sql_hr");
        infoHR.put("uname", "root");
        infoHR.put("pass", "");

        return infoHR;
    }

}
java mysql jdbc
3个回答
-1
投票

只需将id作为最后一行返回,

st.close(); /////////// ERROR IS HERE /////////////
con.close();
return id;

return语句应该是代码块中的最后一条语句。如果不是,那么将永远不会到达它下面的任何代码,因为return语句会将控制权转移到调用当前方法的方法(如果存在,则首先转移到finally块)。

我建议对代码进行改进以清理诸如(对于Java 7+)这样的资源,

  1. 您不需要Class.forName("com.mysql.cj.jdbc.Driver");,因为Java会自动加载它
  2. 使用try-with-resources
try(
    Connection con = DriverManager.getConnection(infoHR.get("url"), infoHR.get("uname"), infoHR.get("pass"));
    Statement st = con.createStatement();
    ResultSet rs = st.executeQuery(query);
        )
        {
Statement st = con.createStatement();
        ResultSet rs = st.executeQuery(query);

        rs.next();
        String id = rs.getString("salary");

        return id;
} finally {
}

这样您可以跳过关闭资源所需的手动步骤


2
投票

问题是您在return语句之后有语句。如果return结束了方法的正常流程,则不会执行后续的close方法。

但是,您的代码未考虑通过异常突然退出方法的情况。在这种情况下,您将无法正确关闭诸如语句和连接之类的资源。

适当的解决方案是使用try-with-resources。您的代码将如下所示:

try (Connection con = DriverManager.getConnection(infoHR.get("url"), infoHR.get("uname"), infoHR.get("pass"));
     Statement st = con.createStatement();
     ResultSet rs = st.executeQuery(query);) {

    rs.next();
    return rs.getString("salary");
}

在try-with-resources块的末尾,将以正确的顺序关闭结果集,语句和连接,即使其中之一无法关闭。


0
投票

您需要先关闭resultSet,然后声明数据库连接才能从数据库中释放所有资源。试试这个:

Connection connection = dataSource.getConnection(infoHR.get("url"), infoHR.get("uname"), infoHR.get("pass"));
try {
Statement statement = connection.createStatement();

try {
ResultSet resultSet = statement.executeQuery("some query");

try {
// Do stuff with the result set.
} finally {
resultSet.close();
}
} finally {
statement.close();
}
} finally {
connection.close();
}

您可以关注此文章以获取更多信息:How to Close JDBC Resources Properly – Every Time

更新:从Java 7开始,您可以使用此:

try (Connection connection = dataSource.getConnection(infoHR.get("url"), infoHR.get("uname"), infoHR.get("pass"));
    Statement statement = connection.createStatement()) {
    try (ResultSet resultSet = statement.executeQuery("some query")) {
        // Do stuff with the result set.
    }
    try (ResultSet resultSet = statement.executeQuery("some query")) {
        // Do more stuff with the second result set.
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.