如何使用在mySQL上运行的JdbcTemplate以可伸缩的方式执行以下SQL。在这种情况下,可扩展意味着:
以下是声明:
INSERT INTO myTable (foo, bar) VALUES ("asdf", "asdf"), ("qwer", "qwer")
假设我有一个包含foo
和bar
字段的POJO列表。我意识到我可以遍历列表并执行:
jdbcTemplate.update("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMap)
但这并不能完成第一个标准。
我相信我也可以执行:
jdbcTemplate.batchUpdate("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMapArray)
但据我所知,这只会编译SQL一次并多次执行,再次失败第一个标准。
似乎通过两个标准的最终可能性是简单地使用StringBuffer
自己构建SQL,但我想避免这种情况。
答案 0 :(得分:33)
您可以使用 BatchPreparedStatementSetter ,如下所示。
public void insertListOfPojos(final List<MyPojo> 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();
}
});
}
答案 1 :(得分:4)
多行插入(使用“行值构造函数”)实际上是SQL-92标准的一部分。看到 http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts
有些数据库不支持这种语法,但很多数据库都支持这种语法。根据我的经验,Derby / Cloudscape,DB2,Postgresql和较新的Hypersonic 2。* +版本都支持这一点。
你对让它作为PreparedStatement工作的担忧是可以理解的,但是我看到过类似的情况,Spring JDBC会自动处理某些查询的项目集合(比如(?)中的位置),但我无法保证这种情况。
我确实找到了一些可能有用的信息(无法添加此帖子的第二个链接) 这可能会有所帮助。
我可以告诉你,对于你的第二个要求(适用于任何数量的参数)可能不可能在最严格的意义上得到满足:我使用过的每个数据库都会产生查询长度限制。
答案 2 :(得分:-1)
您也可以尝试使用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);
答案 3 :(得分:-1)
在我看来,JdbcTemplate的batchUpdate()方法在这种情况下可能会有所帮助(从这里复制http://www.mkyong.com/spring/spring-jdbctemplate-batchupdate-example/):
//insert batch example
public void insertBatch(final List<Customer> 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();
}
});
}
答案 4 :(得分:-4)
你不能在JDBC中执行此操作。在MySQL中,它只是语法糖,但语句的效果与发出几个INSERT语句相同。所以你可以使用batchUpdate,它会产生同样的效果。