我当前正在编写一个与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;
}
}
只需将id作为最后一行返回,
st.close(); /////////// ERROR IS HERE /////////////
con.close();
return id;
return语句应该是代码块中的最后一条语句。如果不是,那么将永远不会到达它下面的任何代码,因为return语句会将控制权转移到调用当前方法的方法(如果存在,则首先转移到finally块)。
我建议对代码进行改进以清理诸如(对于Java 7+)这样的资源,
Class.forName("com.mysql.cj.jdbc.Driver");
,因为Java会自动加载它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 {
}
这样您可以跳过关闭资源所需的手动步骤
问题是您在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块的末尾,将以正确的顺序关闭结果集,语句和连接,即使其中之一无法关闭。
您需要先关闭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.
}
}