使用JdbcTemplate插入多行

如何使用在mySQL上运行的JdbcTemplate以可伸缩的方式执行以下SQL。 在这种情况下,可扩展意味着:

  1. 服务器上只执行一条SQL语句
  2. 它适用于任意数量的行。

这是声明:

INSERT INTO myTable (foo, bar) VALUES ("asdf", "asdf"), ("qwer", "qwer") 

假设我有一个包含foobar字段的POJO列表。 我意识到我可以迭代列表并执行:

 jdbcTemplate.update("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMap) 

但这并不能完成第一个标准。

我相信我也可以执行:

 jdbcTemplate.batchUpdate("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMapArray) 

但据我所知,这只会编译SQL一次并多次执行,再次失败第一个标准。

似乎通过这两个标准的最终可能性是简单地使用StringBuffer自己构建SQL,但我想避免这种情况。

多行插入(使用“行值构造函数”)实际上是SQL-92标准的一部分。 请参见http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts 。

有些数据库不支持这种语法,但很多数据库都支持。 根据我的经验,Derby / Cloudscape,DB2,Postgresql和较新的Hypersonic 2。* +版本都支持这一点。

您对将其作为PreparedStatement工作的担忧是可以理解的,但我看到类似的情况,Spring JDBC会自动处理某些查询的项目集合(例如(?)中的位置),但我无法保证这种情况。

我确实找到了一些可能有用的信息(不能添加到这篇文章的第二个链接),这可能会有所帮助。

我可以告诉你,对于你的第二个要求(适用于任何数量的参数)可能不可能在最严格的意义上得到满足:我使用的每个数据库都会产生查询长度限制,这些限制将发挥作用。

您可以使用BatchPreparedStatementSetter,如下所示。

 public void insertListOfPojos(final List myPojoList) { String sql = "INSERT INTO " + "MY_TABLE " + "(FIELD_1,FIELD_2,FIELD_3) " + "VALUES " + "(?,?,?)"; getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { MyPojo myPojo = myPojoList.get(i); ps.setString(1, myPojo.getField1()); ps.setString(2, myPojo.getField2()); ps.setString(3, myPojo.getField3()); } @Override public int getBatchSize() { return myPojoList.size(); } }); } 

在我看来,JdbcTemplate的batchUpdate()方法在这种情况下可能会有所帮助(从这里复制http://www.mkyong.com/spring/spring-jdbctemplate-batchupdate-example/ ):

 //insert batch example public void insertBatch(final List customers){ String sql = "INSERT INTO CUSTOMER " + "(CUST_ID, NAME, AGE) VALUES (?, ?, ?)"; getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { Customer customer = customers.get(i); ps.setLong(1, customer.getCustId()); ps.setString(2, customer.getName()); ps.setInt(3, customer.getAge() ); } @Override public int getBatchSize() { return customers.size(); } }); } 

你也可以试试jdbcInsert.executeBatch(sqlParamSourceArray)

  // define parameters jdbcInsert = new SimpleJdbcInsert(jdbcTemplate); jdbcInsert.withTableName("TABlE_NAME"); SqlParameterSource[] sqlParamSourceArray = new SqlParameterSource[apiConsumer .getApiRoleIds().size()]; for (int i = 0; i < myCollection.size(); i++) { sqlParamSourceArray[i] = new MapSqlParameterSource().addValue("COL1"); ...................... } // execute insert int[] keys = jdbcInsert.executeBatch(sqlParamSourceArray); 

你不能在JDBC,期间这样做。 在MySQL中它只是语法糖,但语句的效果与发出几个INSERT语句相同。 因此,您可以使用batchUpdate,它将具有相同的效果。