¿Cómo usar una declaración preparada correctamente con Spring JDBCTemplate?

I have to do a select query on a database which I will execute often. It works completely fine with a normal statement:

 List<Invoice> l = this.jdbcTemplate.query(
                     "SELECT id, name, stuff FROM example WHERE amount > ?",
                     new Object[] { "100" }, new RowMapper<Invoice>() {...} );

I execute the above statement very frequently, so for performance reason I want to use a prepared statement. However I'm now unsure how I correctly would use the spring API to achieve this.

I'm confused why spring would like me to give an instance of a PreparedStatementCreator as an argument for query? I thought that it's exactly the point that I do no create a new prepared statement every time I use the query method. So I think something along the line of the following snippet would be absolutely pointless as the prepared statement is created newly every time I call the query-método:

 List<Invoice> l = this.jdbcTemplate.query(
                     new PreparedStatementCreator() {
                         String query = "SELECT id, name, stuff FROM example WHERE amount > ?";
                         public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                              return connection.prepareStatement(query);
                         }
                     },
                     new PreparedStatementSetter() {...}, 
                     new RowMapper<Invoice>() {...} );

Do I have to create my own ReusablePreparedStatementCreator? Which would only create a new method on the first call of createPreparedStatement.

¿Podría el PreparedStatementCreatorFactory ¿ayuadame?

So to rephrase, how would I correctly create a select query that uses a prepared statement with Spring JDBCTemplate to really gain a performance advantage without losing the advantage of the RowMapper?

preguntado el 28 de mayo de 14 a las 12:05

Spring already uses a PreparedStatement, so no need to make it more complex. -

@M.Deinum do you have a official reference to this statment? I looked shortly into the code of JdbcTemplate::query(final String sql, final ResultSetExtractor<T> rse) and could not find any indication that this is true. -

Ver https://github.com/spring-projects/spring-framework/blob/master/… that is the inner class used when using one of the query methods. If you get a new statement or not also depends on your jdbc driver and if it caches statements. -

@M.Deinum thank you! but in this case a new PreparedStatement object is created for each call to the query method. I might be wrong, but I think that does not gives me the improvement I try to achieve. -

It depends on your JDBC provider if it is cached (and thus reused) or if a new one is created. Also I doubt that you want to cache the PreparedStatement because how are you going to execute it for the next connection? (Basically each transaction runs on its own connection). -

1 Respuestas

First of all, I'm not sure you would get a significant performance increase by not recreating the prepared statement every time, because the JDBC driver/database often caches prepared statements.

But if you want to execute multiple queries with a single prepared statement, simply use one of the execute() methods of JdbcTemplate, which creates a prepared statement from a SQL query (or lets you create it), and then executes a callback taking the prepared statement as argument. You can loop inside this callback, and execute the statement as many times you want.

contestado el 28 de mayo de 14 a las 12:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.