java - query - jdbctemplate spring ejemplos
Insertando mĂșltiples filas usando JdbcTemplate (5)
Las inserciones de múltiples filas (que usan "constructores de valor de fila") son de hecho parte del estándar SQL-92. Ver http://en.wikipedia.org/wiki/Insert_(SQL)#Multirow_inserts .
Algunas bases de datos no admiten esta sintaxis, pero muchas sí lo hacen. En mi experiencia, Derby / Cloudscape, DB2, Postgresql y las nuevas versiones de Hypersonic 2. * + Son compatibles con esto.
Su preocupación acerca de que esto funcione como PreparedStatement es comprensible, pero he visto casos similares en los que Spring JDBC maneja automáticamente una colección de elementos para ciertas consultas (como dónde en (?)), Pero no puedo responder por este caso.
Encontré alguna información posiblemente útil en (no puedo agregar el segundo enlace a esta publicación) que podría ser de alguna ayuda.
Puedo decirle que probablemente no sea posible que su segundo requisito (funciona para cualquier número de argumentos) se cumpla en el sentido más estricto: cada base de datos que he utilizado impone limitaciones de longitud de consulta que entrarán en juego.
¿Cómo puedo ejecutar el siguiente SQL de forma escalable utilizando JdbcTemplate ejecutándose en mySQL? En este caso, escalable significa:
- Solo se ejecuta una sentencia SQL en el servidor.
- Funciona para cualquier número de filas.
Aquí está la declaración:
INSERT INTO myTable (foo, bar) VALUES ("asdf", "asdf"), ("qwer", "qwer")
Supongamos que tengo una lista de POJO con foo
y campos de bar
. Me doy cuenta de que solo podría iterar sobre la lista y ejecutar:
jdbcTemplate.update("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMap)
pero eso no cumple el primer criterio.
Creo que también podría ejecutar:
jdbcTemplate.batchUpdate("INSERT INTO myTable(foo, bar) VALUES (?, ?)", paramMapArray)
pero por lo que puedo decir, eso solo compilará el SQL una vez y lo ejecutará varias veces, fallando nuevamente el primer criterio.
La posibilidad final, que parece pasar ambos criterios, sería simplemente construir el SQL yo mismo con un StringBuffer
, pero me gustaría evitar eso.
Me parece que el método batchUpdate () de JdbcTemplate podría ser útil en este caso (copiado desde aquí 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();
}
});
}
No puedes hacer esto en JDBC, punto. En MySQL solo es azúcar sintáctica, pero el efecto de la declaración será el mismo que emitir varias declaraciones INSERT. Así que puedes usar batchUpdate y tendrá el mismo efecto.
Puedes usar BatchPreparedStatementSetter como abajo.
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();
}
});
}
También puedes probar con 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);