据我了解,Java中PreparedStatement的使用是我们可以多次使用它。
但是我在使用Spring JDBC的PreparedStatementCreator时有些困惑。
例如考虑以下代码,
public class SpringTest {
JdbcTemplate jdbcTemplate;
PreparedStatementCreator preparedStatementCreator;
ResultSetExtractor<String> resultSetExtractor;
public SpringTest() throws SQLException {
jdbcTemplate = new JdbcTemplate(OracleUtil.getDataSource());
preparedStatementCreator = new PreparedStatementCreator() {
String query = "select NAME from TABLE1 where ID=?";
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
return connection.prepareStatement(query);
}
};
resultSetExtractor = new ResultSetExtractor<String>() {
public String extractData(ResultSet resultSet) throws SQLException,
DataAccessException {
if (resultSet.next()) {
return resultSet.getString(1);
}
return null;
}
};
}
public String getNameFromId(int id){
return jdbcTemplate.query(preparedStatementCreator, new Table1Setter(id), resultSetExtractor);
}
private static class Table1Setter implements PreparedStatementSetter{
private int id;
public Table1Setter(int id) {
this.id =id;
}
@Override
public void setValues(PreparedStatement preparedStatement) throws SQLException {
preparedStatement.setInt(1, id);
}
}
public static void main(String[] args) {
try {
SpringTest springTest = new SpringTest();
for(int i=0;i<10;i++){
System.out.println(springTest.getNameFromId(i));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
根据这段代码,当我调用 springTest.getNameFromId(int id) 方法时,它从给定的 id 返回名称,这里我使用PreparedStatementCreator 来创建PreparedStatement,使用PreparedStatementSetter 来设置输入参数,并从 ResultSetExtractor 获得结果。
但性能非常慢。
在调试并研究了PreparedStatementCreator和JdbcTemplate内部发生的情况之后,我知道PreparedStatementCreator每次都会创建新的PreparedStatement......!
每次我调用方法 jdbcTemplate.query(preparedStatementCreator,preparedStatementSetter,resultSetExtractor) 时,它都会创建新的PreparedStatement,这会降低性能。
这是使用PreparedStatementCreator的正确方法吗?因为在这段代码中我无法重用PreparedStatement。如果这是使用PreparedStatementCreator的正确方法,那么如何获得PreparedStatement的可重用性的好处呢?