Java: inserte varias filas en MySQL con PreparedStatement
Quiero insertar varias filas en una tabla MySQL a la vez usando Java. El número de filas es dinámico. En el pasado estaba haciendo...
for (String element : array) {
myStatement.setString(1, element[0]);
myStatement.setString(2, element[1]);
myStatement.executeUpdate();
}
Me gustaría optimizar esto para usar la sintaxis compatible con MySQL:
INSERT INTO table (col1, col2) VALUES ('val1', 'val2'), ('val1', 'val2')[, ...]
pero con a PreparedStatement
no conozco ninguna forma de hacer esto ya que no sé de antemano cuántos elementos array
contendrá. Si no es posible con a PreparedStatement
, ¿de qué otra manera puedo hacerlo (y aun así escapar de los valores de la matriz)?
Puede crear un lote PreparedStatement#addBatch()
y ejecutarlo mediante PreparedStatement#executeBatch()
.
Aquí hay un ejemplo de inicio:
public void save(List<Entity> entities) throws SQLException {
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_INSERT);
) {
int i = 0;
for (Entity entity : entities) {
statement.setString(1, entity.getSomeProperty());
// ...
statement.addBatch();
i++;
if (i % 1000 == 0 || i == entities.size()) {
statement.executeBatch(); // Execute every 1000 items.
}
}
}
}
Se ejecuta cada 1000 elementos porque algunos controladores JDBC y/o bases de datos pueden tener una limitación en la longitud del lote.
Ver también :
- Tutorial de JDBC: uso de PreparedStatement
- Tutorial de JDBC: uso de objetos de declaración para actualizaciones por lotes
Cuando se utiliza el controlador MySQL, debe establecer el parámetro de conexión rewriteBatchedStatements
en verdadero ( jdbc:mysql://localhost:3306/TestDB?**rewriteBatchedStatements=true**)
.
Con este parámetro, la declaración se reescribe para inserción masiva cuando la tabla se bloquea solo una vez y los índices se actualizan solo una vez. Entonces es mucho más rápido.
Sin este parámetro, la única ventaja es un código fuente más limpio.
Si puede crear su declaración SQL dinámicamente, puede realizar la siguiente solución:
String myArray[][] = { { "1-1", "1-2" }, { "2-1", "2-2" }, { "3-1", "3-2" } };
StringBuffer mySql = new StringBuffer("insert into MyTable (col1, col2) values (?, ?)");
for (int i = 0; i < myArray.length - 1; i++) {
mySql.append(", (?, ?)");
}
myStatement = myConnection.prepareStatement(mySql.toString());
for (int i = 0; i < myArray.length; i++) {
myStatement.setString(i, myArray[i][1]);
myStatement.setString(i, myArray[i][2]);
}
myStatement.executeUpdate();