使用带有JDBCTemplate的预准备语句

我正在使用JDBC模板,并希望使用预准备语句从数据库中读取。 我在.csv文件中迭代多行,并在每一行上执行一些带有相应值的SQL select查询。

我想加快从数据库中读取数据,但我不知道如何让JDBC模板与预处理语句一起使用。

有PreparedStatementCreator和PreparedStatementSetter 。 在此示例中 ,它们都是使用匿名内部类创建的。 但是在PreparedStatementSetter类中,我无法访问我想在预准备语句中设置的值。

因为我正在迭代.csv文件,所以我不能将它们硬编码为String,因为我不知道它们。 我也无法将它们传递给PreparedStatementSetter,因为构造函数没有参数。 将我的价值观设定为最终值也是愚蠢的。

我习惯于创建准备好的语句非常简单。 就像是

PreparedStatement updateSales = con.prepareStatement( "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); updateSales.setInt(1, 75); updateSales.setString(2, "Colombian"); updateSales.executeUpdate(): 

就像在这个Java教程中一样 。

默认情况下,如果您只使用.update(String sql, Object ... args)表单,则JDBCTemplate会在内部执行自己的PreparedStatement 。 Spring和您的数据库将为您管理编译的查询,因此您不必担心打开,关闭,资源保护等等。spring的节约之一。 Spring 2.5的文档链接。 希望它能让事情更加清晰。 此外,语句缓存可以在JDBC级别完成,例如至少部分Oracle的JDBC驱动程序。 这比我能胜任的细节要多得多。

 class Main { public static void main(String args[]) throws Exception { ApplicationContext ac = new ClassPathXmlApplicationContext("context.xml", Main.class); DataSource dataSource = (DataSource) ac.getBean("dataSource"); // DataSource mysqlDataSource = (DataSource) ac.getBean("mysqlDataSource"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); String prasobhName = jdbcTemplate.query( "select first_name from customer where last_name like ?", new PreparedStatementSetter() { public void setValues(PreparedStatement preparedStatement) throws SQLException { preparedStatement.setString(1, "nair%"); } }, new ResultSetExtractor() { public Long extractData(ResultSet resultSet) throws SQLException, DataAccessException { if (resultSet.next()) { return resultSet.getLong(1); } return null; } } ); System.out.println(machaceksName); } } 

请尝试以下方法:

 PreparedStatementCreator creator = new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement updateSales = con.prepareStatement( "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); updateSales.setInt(1, 75); updateSales.setString(2, "Colombian"); return updateSales; } }; 

我将准备好的语句处理分解为至少一个方法。 在这种情况下,因为没有结果它相当简单(假设连接是一个不改变的实例变量):

 private PreparedStatement updateSales; public void updateSales(int sales, String cof_name) throws SQLException { if (updateSales == null) { updateSales = con.prepareStatement( "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?"); } updateSales.setInt(1, sales); updateSales.setString(2, cof_name); updateSales.executeUpdate(); } 

那时,只需要调用:

 updateSales(75, "Colombian"); 

与其他东西集成非常简单,是吗? 如果你多次调用该方法,更新将只构建一次,这将使事情更快。 好吧,假设你不做疯狂的事情,比如在自己的交易中做每次更新……

请注意,类型是固定的。 这是因为对于任何特定的查询/更新, 应该修复它们以便允许数据库有效地完成其工作。 如果您只是从CSV文件中提取任意字符串,请将它们作为字符串传递。 也没有锁定; 更好地保持从单个线程使用单个连接。

我现在用PreparedStatement尝试了一个select语句,但事实certificate它并不比Jdbc模板快。 也许,正如mezmo建议的那样,它会自动创建预备语句。

无论如何,我的SQL SELECT太慢的原因是另一个。 在WHERE子句中,我总是使用运算符LIKE ,当我想要做的就是找到完全匹配。 正如我发现LIKE搜索模式因此非常慢。

我正在使用operator = now,而且速度要快得多。