JDBC Batch , o ejecuciones batch es una de las características que muchas veces nos olvidamos que están disponibles en JDBC y pueden mejorar el rendimiento de las actualizaciones que ejecutemos. Normalmente cuando uno trabaja con JDBC o tecnologías similares puede ejecutar varias consultas de inserción seguidas.
sentencia.executeQuery(“insert into persona (nombre,apellidos,edad) values ('pepe','perez',30)"); sentencia.executeQuery(“insert into persona (nombre,apellidos,edad) values ('maria','sanchez',20)"); sentencia.executeQuery(“insert into persona (nombre,apellidos,edad) values ('gema','alvarez',15)");
Aunque esto nos parezca correcto, dependiendo de la circunstancia puede no serlo, ya que cada vez que realizamos una llamada al servidor realizaremos una única consulta de inserción y en rendimiento debido al tráfico de red bajará.
JDBC Batch
Para solventar este problema JDBC soporta los trabajos Batch. Estos trabajos agrupan un conjunto de consultas para ejecutarlas todas de forma simultanea.
Vamos a ver el código :
package com.arquitecturajava.clase1; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class ProgramaMain { public static void main(String[] args) { Connection conexion = null; Statement sentencia = null; try { Class.forName("com.mysql.jdbc.Driver"); String cadenaConexion = "jdbc:mysql://localhost:3306/curso"; conexion = DriverManager.getConnection(cadenaConexion, "root", ""); sentencia = conexion.createStatement(); sentencia.addBatch("insert into persona (nombre,apellidos,edad) values ('pepe','perez',30)"); sentencia.addBatch("insert into persona (nombre,apellidos,edad) values ('maria','sanchez',20)"); sentencia.addBatch("insert into persona (nombre,apellidos,edad) values ('gema','alvarez',15)"); sentencia.executeBatch(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (sentencia != null) try { sentencia.close(); } catch (SQLException e) { e.printStackTrace(); } if (conexion != null) try { conexion.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Como podemos observar el método de addBatch va añadiendo las diferentes consultas al grupo. Por último el método executeBatch las ejecuta de golpe contra la base de datos. Este método devuelve un array de enteros con las filas afectadas por cada consulta.
Otros artículos relacionados :
Hola Cecilio, quisiera consultarte si existe una manera para que en caso de que uno de los registros que se quiera insertar falle, este registro no afecte la inserción de los otros registros del bloque, es decir, si voy a insertar 50 registros y fallan 2, se inserten los 48 que están bien.
Mil gracias, saludos.
Buenos dias Cecilio, quisiera hacerte una consulta, si inserto registros en una tabla con executeBatch en bloques de 50 por ejemplo, si uno de los registros falla por alguna razón, como hago para que solo ese registro no se inserte y queden los otros 49 registros que si estaban correctos?
Muchas gracias.
https://stackoverflow.com/questions/29852748/jdbc-preparedstatement-batch-continue-insert-on-error podría valer?
Hola!
Si la query a ejecutar es de tipo “si no existe insertar sino actualizar” conviene ejecutar asi?
o conviene solo insertar o actualizar por separado?
tienen limite de registros? digo por la performance.
gracias.
En principio es mejor ejecutar varios
Podría con el batch, hacer select y mostrarlo en un jtable ??
Si pero yo creo que poco aportaría ya que es una sola query
Hola muy buen tuto, una pregunta realice el ejercicio pero no me inserta todos mis registros con bacht, también realice la prueba con ejecución normal y si que me inserto todo, tendrás alguna idea.
Saludos
puede ser que el driver que tienes no soporte operaciones batch
Muy claro y conciso. Muchas gracias.
gracias 🙂
Excelente el articulo
gracias 🙂
Muy interesante. Cecilio, en jpa como se haria esto? o se configura en las propiedades del persistence.xml?
Depende del provider de JPA mira el siguiente artículo : http://java-persistence-performance.blogspot.com.es/2013/05/batch-writing-and-dynamic-vs.html
Interesante. Desconocia el concepto de Jdbc Batch.
Usando Ibatis resolví este problema haciendo un insert de una lista de objetos. Asi no me realizaba tropecientas mil conexiones a BBDD
INSERT INTO nombreTabla (id)
VALUES
#{element.id}
Cada framework tiene su enfoque 🙂