我遇到过这种模式。需要多个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();}
}
答案 0 :(得分:1)
您应该要做的是使用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
}
}
答案 1 :(得分:1)
重用连接不是反模式,完全可以。重用连接是两条语句在同一本地JDBC事务中执行的唯一方法。如果您正在编写访问关系数据库的应用程序,则应该了解事务。
实现异常处理的方式容易出错,因为如果在关闭任何资源时引发异常,则以后的资源不会被关闭。如果关闭prepareStatement引发异常,则连接不会关闭。 try-with-resources是一种改进,但是the way try-with-resources handles the edge cases使我避免使用JDBC,而使用嵌套的try-finally块。
如果这里有一个反模式,则它是直接使用JDBC的,它是非常低级的,涉及很多剪切和粘贴操作,并且不便于使用事务或连接池。使用Spring会处理一些细节,例如划分数据库事务,使用连接池以及为您关闭资源。