Java 如何在 Spring JDBCTemplate 中正确使用准备好的语句?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23910354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 08:58:12  来源:igfitidea点击:

How to use a prepared statement correctly with Spring JDBCTemplate?

javaspringjdbctemplate

提问by leo

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.

我非常频繁地执行上述语句,因此出于性能原因,我想使用准备好的语句。但是,我现在不确定如何正确使用 spring API 来实现这一点。

I'm confused why spring would like me to give an instance of a PreparedStatementCreatoras an argument for query? I thought that it's exactly the point that I do notcreate 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-method:

我很困惑为什么 spring 要我给出一个 a 的实例PreparedStatementCreator作为查询的参数?我认为这正是我每次使用查询方法时都不会创建新的准备好的语句的重点。因此,我认为以下代码段中的某些内容绝对毫无意义,因为每次调用query-method 时都会新创建准备好的语句:

 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.

我必须创建自己的ReusablePreparedStatementCreator吗?这只会在第一次调用createPreparedStatement.

Could the PreparedStatementCreatorFactoryhelp me?

可以在PreparedStatementCreatorFactory帮助我吗?

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?

所以换个说法,我将如何正确创建一个选择查询,该查询使用带有 Spring JDBCTemplate 的准备好的语句来真正获得性能优势而不会失去 RowMapper 的优势?

采纳答案by JB Nizet

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.

首先,我不确定每次不重新创建准备好的语句是否会显着提高性能,因为 JDBC 驱动程序/数据库经常缓存准备好的语句。

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.

但是如果你想用一个准备好的语句执行多个查询,只需使用execute()JdbcTemplate的方法之一,它从一个 SQL 查询创建一个准备好的语句(或者让你创建它),然后执行一个回调,将准备好的语句作为争论。您可以在此回调中循环,并根据需要多次执行该语句。