Java 无法解决close preparedsStatement的SonarQube错误
我有一个JDBCStreamTemplate类,它调用类中的另外两个方法——JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable JDBCStreamTemplate类方法具有connection和preparedStatement。sql和connection的参数通过构造函数传递给JDBCStreamRow和JDBCStreamResultSet JDBCStreamRow和JDBCStreamResultSet类中的连接和预准备状态正在关闭。但是SONARQube给了bug连接和PreparedStatement需要在JDBCStreamTemplate类中关闭 你能告诉我如何解决这个错误吗 我试图通过将finally放入JDBCStreamTemplate来关闭PS和CON,但它说语句在任何预期结果之前关闭。 下面的代码是调用JdbcStreamResultSet构造函数的JDBCStreamTemplate类方法Java 无法解决close preparedsStatement的SonarQube错误,java,jdbc,sonarqube,prepared-statement,Java,Jdbc,Sonarqube,Prepared Statement,我有一个JDBCStreamTemplate类,它调用类中的另外两个方法——JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable JDBCStreamTemplate类方法具有connection和preparedStatement。sql和connection的参数通过构造函数传递给JDBCStreamRow和JDBCStreamResultSet JDBCStreamRow和JDBCStreamResultSet类中的连接和预准备状态正在
try {
Connection connection = DataSourceUtils.getConnection(this.getDataSource());
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setFetchSize(5000);
this.newArgPreparedStatementSetter(args).setValues(preparedStatement);
jdbcStreamResultSet = new JdbcStreamResultSet(qRef, connection, preparedStatement);
} catch (SQLException sqle) {
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef, JdbcUtilities.formatException(sqle));
throw sqle;
} catch (CannotGetJdbcConnectionException ce) {
SQLException sqle = new SQLException(ce.getMostSpecificCause());
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef, Helpers.getExceptionMessage(sqle));
throw sqle;
}
return jdbcStreamResultSet;
}
但是SONARQube给了bug连接和PreparedStatement需要在JDBCStreamTemplate类中关闭
是的,很好的做法是,打开某个东西的代码也应该是负责关闭它的代码!在调用树上下分解该职责(即在一种方法中“创建/打开”,在另一种方法中关闭)会使跟踪控制流变得困难,因此会自找麻烦
JDBCStreamRow和JDBCStreamResultSet类中的连接和预准备状态正在关闭
另一件事是,我在代码中没有看到任何“关闭”的内容。您说在其他类中关闭了connection和preparedStatement,但是
a) 你也不会关闭其他的课程,而且
b) 我们没有这些的代码
所以。。。。。。。我将忽略您的其他类,而是确保在这段代码中关闭connection和preparedStatement
JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable
connection和preparedStatement都实现了AutoCloseable,所以希望您能够将我将要使用的相同思想应用到您自己的类中
了解如何使用自动关闭
,这一点很重要。这并不意味着JVM在关闭对象时会自行做出任意决定。相反,这意味着当在try with resources块的“resources”部分中使用该对象时,该对象将被关闭
对于connection和preparedStatement,这意味着我们可以将您的代码更改为使用try with resources,以便:
try ( Connection connection = DataSourceUtils.getConnection(this.getDataSource());
PreparedStatement preparedStatement = connection.prepareStatement(sql);
)
{
connection.setAutoCommit(false);
preparedStatement.setFetchSize(5000);
this.newArgPreparedStatementSetter(args).setValues(preparedStatement);
jdbcStreamResultSet = new JdbcStreamResultSet(qRef, connection, preparedStatement);
} catch (SQLException sqle) {
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef,
JdbcUtilities.formatException(sqle));
throw sqle;
} catch (CannotGetJdbcConnectionException ce) {
SQLException sqle = new SQLException(ce.getMostSpecificCause());
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef, Helpers.getExceptionMessage(sqle));
throw sqle;
}
return jdbcStreamResultSet;
}
使用此布局,连接和preparedStatement保证无论发生什么情况(并且以正确的顺序)都会关闭,SONARQube应该很高兴