Java 在保持代码干净的同时重用准备好的语句的最佳实践?

Java 在保持代码干净的同时重用准备好的语句的最佳实践?,java,prepared-statement,Java,Prepared Statement,TL;DR:在Java中重用PreparedStatement对象而不造成代码混乱的推荐方法是什么 如果我想重用它们,我必须在代码的早期定义它们,这会变得一团糟 如果我在需要之前不创建它们,我可以保持代码整洁,但是我不能重用这些对象 我有这样一种方法: PreparedStatement psQuery=conn.prepareStatement(“选择…”); PreparedStatement psChild=conn.prepareStatement(“选择…其中父项=?和…); R

TL;DR:在Java中重用
PreparedStatement
对象而不造成代码混乱的推荐方法是什么

  • 如果我想重用它们,我必须在代码的早期定义它们,这会变得一团糟
  • 如果我在需要之前不创建它们,我可以保持代码整洁,但是我不能重用这些对象

我有这样一种方法:

PreparedStatement psQuery=conn.prepareStatement(“选择…”);
PreparedStatement psChild=conn.prepareStatement(“选择…其中父项=?和…);
ResultSet rsQuery=psQuery.executeQuery();
while(rsQuery.next()){
psChild.setInt(1,rsQuery.getInt(“id”);
psChild.executeQuery();
...
}
我首先创建两个
preparedStatement
,然后在每次需要执行这些特定SQL查询时重用它们。我不会在循环中定义
psChild
,因为这样我会在每次迭代中创建一个新的准备好的语句,而不仅仅是重用它

现在,我的代码要复杂得多。我实际上使用了13个不同的
preparedStatement
实例,代码分布在几百行中。我很想把它分成不同的方法,但我不知道如何正确地做。我可以想出两个选择。第一个是我现在正在做的,只是分成了几个方法:

PreparedStatement psQuery=conn.prepareStatement(“选择…”);
PreparedStatement psChild=conn.prepareStatement(“选择…其中父项=?和…);
ResultSet rsQuery=psQuery.executeQuery();
while(rsQuery.next()){
processChildren(rsQuery.getInt(“id”),psChild);
}
问题是,我最终得到了一个带有此签名的
processChildren

私有静态void processChild(
...,
最终编制报表psFoo,
最终编制的psBar报表,
最终编制报表psDoc,
最终编制报表psGrumpy,
最终编制的报表,
最终编制的报表,
最终编制报表psDopey,
最后准备的声明很害羞,
最终编制报表PSSNEZY,
最终编制报表PSYETANOTHER,
最终编制报表PSA和其他报表,
最终编制报表psLastOne,
...) {
不太好

另一种选择是在我需要的方法中创建每个准备好的语句。这会更干净,但与在循环中创建它们是一样的:我不会重用它们

还有另一种选择,将变量声明为类属性,这样我可以先创建它们,然后重用它们,而无需将“children method”签名弄得乱七八糟。但这感觉更加错误,就像使用全局变量一样。更糟糕的是,13“global”所有变量都具有相同的类和非常相似的名称。我不可能这样做

我怎样才能继续

注意:我知道有更好的持久性解决方案,比如JPA。我不是在寻找一种替代方案来代替预先准备好的语句,我只是想知道在像我这样的情况下通常的方法是什么



编辑:我似乎过于简化了我的示例。这更接近于我需要做的事情:

  • 从数据库1检索所有记录
  • 对于其中的每一个(第一个循环):
  • 检查它是否存在于另一个数据库2中
  • 如果没有,请在数据库2中创建它,然后:
  • 从数据库1检索所有子项
  • 对于每个子级(第二个循环):
  • 检查数据库2中是否存在子项
  • 如果没有,则插入它

  • 所以我有两层嵌套循环,我无法摆脱。在循环内部一遍又一遍地创建准备好的语句似乎是个糟糕的主意。

    很难对这13条语句进行评论。但是对于所展示的代码,您可以编写一个连接,并且只使用一条准备好的语句。是的,让它们成为类变量会很糟糕,它将不是线程安全的。准备好的语句不能跨不同的连接重用。为什么要在循环中创建它们?不能创建一个包含辅助SQL的SQL吗?正如其他人所说,在给定的示例中,您可能可以将这两个语句合并为一个。如果忽略这一点,将其拆分为int怎么样o多个方法,每个方法都有自己的语句?
    findParents
    用于返回某些对象集合的第一个语句,以及
    findChildren
    用于获取该集合并返回其他集合。似乎我过于简化了我的示例:)我将编辑questionPreparedStatements仍然不能用于Concur因此,我倾向于在本地尝试使用wtih资源。也有JDBC模板库,如XML格式。20个PreparedStatement变量太难看了。很难对13个语句进行评论。但是对于显示的代码,您可以编写一个连接,并且只使用一个prepared语句。是的,让它们成为类变量会很糟糕,不会不能是线程安全的。准备好的语句不能跨不同的连接重用。为什么要在循环中创建它们?难道不能创建一个包含辅助SQL的SQL吗?正如其他人所说,在给定的示例中,您可能可以将这两条语句合并为一条。如果忽略这一点,将其拆分为多条语句怎么样方法,每个方法都有自己的语句?
    findParents
    用于返回某些对象集合的第一个语句,以及
    findChildren
    将获取该集合并返回其他集合。似乎我过于简化了我的示例:)我将编辑questionPreparedStatements仍然不能同时使用,因此我不能结束在本地尝试wtih资源。还有JDBC模板库,如XML格式。20个PreparedStatement变量太难看了。