连续的 PreparedStatement 良好实践
Posted
技术标签:
【中文标题】连续的 PreparedStatement 良好实践【英文标题】:Consecutive PreparedStatement good practice 【发布时间】:2011-08-30 15:09:40 【问题描述】:我正在连续执行几个SELECT
s,我想知道如何处理PreparedStatement
s。
示例代码:
//Connection conn is already declared
PreparedStatement pstmt = null;
ResultSet rset = null;
try
String sql = "SELECT ...";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, someVar);
rset = pstmt.executeQuery();
// Use ResultSet
// A different query
sql = "SELECT ...";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, someVar);
rset = pstmt.executeQuery();
// Use ResultSet
catch (SQLException e)
// Handle
finally
if (rset != null)
rset.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
现在的问题是,在每次使用/使用不同的语句后关闭PreparedStatement
s 会更好还是完全没有区别?
我找到了一些关于重用 PreparedStatement
的信息,它总是有相同的查询,但我不确定使用不同的查询。
【问题讨论】:
我很确定在这个例子中使用同一个和使用两个之间的差异可以忽略不计。但是,如果您在一个循环中多次使用它们,那么有两个将是可行的方法,因为您不必每次都在数据库上重新编译查询。 如果您有不同的查询,您需要使用多个语句或在语句中构建开关(如果可能) - 我会选择更易于维护和可读的选项并使用多个语句。跨度> 这是一个非常奇怪的结构。结果是否要关联/组合成一个最终结果?是的?您熟悉 SQLJOIN
子句吗?我会花时间学习它,这样你就可以得到一个 SQL 查询。或者,如果它是两个完全独立的查询,我会在单独的方法体中执行它。
@BalusC 是的,我知道JOIN
s。它们是 2 个不相关的 SELECT
s,用于生成报告。
那就去学习JOIN
吧。
【参考方案1】:
您使用的不是同一个PreparedStatement
,工厂方法Connection.prepareStatement
每次调用它时都会返回一个新实例。 PreparedStatement.executeQuery
与 ResultSet
做同样的事情。您只是使用相同的变量。
这意味着您正在泄漏资源 - 第一个 PreparedStatement
和 ResultSet
- 每次调用此方法时,它们都不会被关闭。
我的建议是使用 Spring 的 JdbcTemplate
,它将为您正确处理这些数据库资源,并将您的代码分成两种方法。
【讨论】:
换句话说,您需要为多个语句和结果集设置单独的局部变量,并在finally
中将它们全部关闭。
这里的***答案说你可以重复使用ResultSet
***.com/questions/12903115/reusing-resultset
@ethamjyx 两个示例都没有重用ResultSet
,它们重用了引用ResultSet
的变量。在您引用的答案中,没有资源泄漏,因为 Statement
被重用(如上所述隐式关闭 ResultSet
);在上面的代码中,情况并非如此,并且存在资源泄漏。归根结底,我认为这两个代码示例都很糟糕——重用这样的变量,恕我直言,很糟糕。至于资源的关闭,这应该是明确的,让任何阅读代码的人都清楚发生了什么。以上是关于连续的 PreparedStatement 良好实践的主要内容,如果未能解决你的问题,请参考以下文章
BGD 通信15-1 150206102 王嘉良 DDS信号发生器