JPA – Improve performance

En estos días tuve una tarea relativamente sencilla que en resumen consistía pasar los datos de una tabla hacia otra, previo algunos procesos de transformación y cambio (esto lo hice invocando código dinámicamente, luego se los comento); así ya se pueden dar una idea de lo que debía hacer, lo que debo destacar aquí es el volumen de datos ya tenía 1450000 filas aproximadamente.

Lo que utilicé para la tarea fue JDK1.8, JPA como base de datos MySQL. Como se pueden imaginar la tarea es bastante sencilla un par de entidades JPA que representan las tablas origen y destino, y lo único que queda es ejecutar las transformaciones. El verdadero problema llegó cuando traté de ejecutar el proceso sobre todo el conjunto de datos. Llegué a procesar 100000 registros en 230 minutos, ese resultado era intolerable.

La tarea se convirtió en mejorar el desempeño de JPA, luego de buscar encontré está página este blog  Java Persistence Performance – How to improve JPA performance by 1,825% y traté de implementar algunas de las recomendaciones que ahí se hacen. En resumen implementé las siguientes (la paginación ya la tenía):

  1. Batch writing, optimización número 8. Agregué las siguientes líneas a mi persistence.xml:
    <property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
    <property name="eclipselink.jdbc.batch-writing.size" value="1000" />
  2. Implementé también la optimización 11, agregando las siguientes líneas al mismo archivo
    <property name="eclipselink.persistence-context.flush-mode" value="commit"/>
    <property name="eclipselink.persistence-context.close-on-commit" value="true"/>
    <property name="eclipselink.persistence-context.persist-on-commit" value="false"/>

    No me quise eliminar los mensajes de log.

  3. Finalmente agregué un parámetro al url de mi conexión, quedando así
    <property name="javax.persistence.jdbc.url" value="jdbc:mysql://<myserver>:<myport>/<mydatabase>?rewriteBatchedStatements=true"/>

    Esto lo encontré en el mismo blog, pero la entrada Batch Writing, and Dynamic vs Parametrized SQL, how well does your database perform?

Con éstas configuraciones logré procesar el 1450000 registros en 19 minutos, no cambié nada en el código únicamente modifiqué el archivo de configuración de JPA.

Espero que éstas líneas les puedan ayudar a ustedes también.

JavaFX e interacción con base de datos

Buscando ejemplos de aplicaciones JavaFx, me he encontrado con el siguinte blog JFXStudio, el mismo que muestra una gran cantidad de ejemplos sobre JavaFx, acompañados de su código fuente.

Uno de los ejemplos que más me ha llamado la atención es uno que trabaja con base de datos. El ejemplo es una evolución de otro, que se detalla aquí. En la evolución se puede ver una interfaz más desarrollada y enriquecida que la original.

Lo interesante del post original es que detalla el trabajo con base de datos, una de las tareas que son necesarias en cualquier tipo de aplicación. En éste ejemplo podemos ver el potencial para la creación de GUI que posee JavaFX y cómo interactuar con bases de datos. Pueden encontrar el código fuente del proyecto de NetBeans.

Un imagen de ejemplo: tomada desde JavaFXStudio

”]GUI JavaFX y base de datos

Espero que les ayude.

Obtener imagenes desde una base datos

Hace algún tiempo escribí el post JFrame con Imagen de Fondo y surgieron varios comentarios en donde se preguntaban ¿cómo obtener, desde una base de datos, las imágenes? Hace una semana respondí a ésta pregunta, pero creo que es necesario hacer un nuevo post con éste tema.

Imaginemos que tenemos una base de datos que contiene una tabla llamada IMAGENES, que tiene una columna tipo BLOB (denominada FOTO) y un identificador (denominado ID). Para consultar desde la base datos la foto podemos hacer la siguiente consulta:

ResultSet rs = stmt.executeQuery(“SELECT FOTO FROM IMAGENES WHERE ID = 1”);

rs.next(); //Esto hacía falta

byte[] img = rs.getBytes(“FOTO”);

Debido a que un campo tipo BLOB almacena información en formato binario utilizamos un arreglo de bytes para leerlo. Hasta aquí he leído desde la base de datos una imagen con bytes, pero ¿qué debo hacer para convertirla en imagen y agregarla a un botón?

Para responder a ésta pregunta utilizaré un código que encontré en un artículo publicado en el sitio oficial de NetBeansEnd-to-End Web Service Creation and Consumption in NetBeans IDE 6.0

private Image getImage(byte[] bytes, boolean isThumbnail) throws IOException {

ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
Iterator readers = ImageIO.getImageReadersByFormatName(”jpeg”);
ImageReader reader = (ImageReader) readers.next();
Object source = bis; // File or InputStream
ImageInputStream iis = ImageIO.createImageInputStream(source);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
if (isThumbnail) {

param.setSourceSubsampling(4, 4, 0, 0);

}
return reader.read(0, param);

}
El código anterior recibe como uno de sus parámetros, un arreglo de bytes y devuelve un objeto tipo Image. Entonces se podría completar el código así:

Image imagen = getImage(img, false);
Icon icon = new ImageIcon(imagen);
btnBoton.setIcon(icon);

Y con ésto tendríamos un botón con un icono que se obtuvo de una base de datos. Espero que sea de su ayuda.

Powered by ScribeFire.