我遇到过这种模式。当您需要执行多个SQL语句时,在单个方法中重用Connection
对象是否可以?
我最初的想法是在继续之前关闭所有资源:
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = ConnectionFactory.getConnection();
ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?");
ps.setString(1, "val");
rs = ps.executeQuery();
// get values used to determine the next statement type
} catch (SQLException e) {
LOG.error("SQL failed.", e);
} finally {
if(rs != null){rs.close();}
if(ps != null){ps.close();}
if(conn != null){conn.close();}
}
// Then another SQL statement is needed (either an UPDATE or INSERT).
// Repeat the same pattern to open, use and close the connection
做以下事情是否安全?如果它是安全的,是否有真正的好处?
//... boilerplate
try {
conn = ConnectionFactory.getConnection();
ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?");
ps.setString(1, "val");
rs = ps.executeQuery();
// ... more
ps = conn.prepareStatement("UPDATE MYTABLE SET COL=?")
// ... etc
} finally {
if(rs != null){rs.close();}
if(ps != null){ps.close();}
if(conn != null){conn.close();}
}
你应该做的是使用try-with-resources:
//... boilerplate
try (Connection conn = ConnectionFactory.getConnection()) {
try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?")) {
ps.setString(1, "val");
try (ResultSet rs = ps.executeQuery()) {
// ... more
}
}
try (PreparedStatement ps = conn.prepareStatement("UPDATE MYTABLE SET COL=?")) {
// ... etc
}
}
重用连接不是反模式,它完全没问题。重用连接是两个语句在同一本地JDBC事务中执行的唯一方法。如果您正在编写访问关系数据库的应用程序,则应了解事务。
实现异常处理的方式容易出错,因为如果在关闭任何资源时抛出异常,则以后的资源不会被关闭。如果关闭preparedStatement会抛出异常,则连接不会关闭。 try-with-resources将是一种改进,但是the way try-with-resources handles the edge cases让我避免使用JDBC来支持嵌套的try-finally块。
如果这里有反模式,它直接使用JDBC,它是非常低级的,涉及大量的剪切和粘贴,并且不容易使用事务或连接池。使用Spring可以处理详细信息,例如划分数据库事务,使用连接池以及为您关闭资源。