Creador y propietario de AdictosAlTrabajo.com, Director General de Autentia S.L., Ingeniero Técnico de Telecomunicaciones y Executive MBA por el Instituto de Empresa 2007.
Twitter: Follow @rcanalesmora
Autor de los Libros: Planifica tu éxito: de aprendiz a empresario y Informática profesional, las reglas no escritas para triunfar en la empresa
Puedes consultar mi CV y alguna de mis primeras aplicaciones (de los 90) aquí
Fecha de publicación del tutorial: 2004-05-22
Imágenes, Java/JDBC y MySQL
He recibido otra consulta que me ha gustado "¿como puedo almacenar y recuperar imágenes en MySQL desde Java?". Hoy os vamos a contar paso a paso como se puede hacer..
Muchos de vosotros que escribís preguntando por problemas en vuestros programas, debéis ser comprensivos y tener en cuenta que recibimos muchas peticiones diarias, no podemos atenderlas todas (el tiempo no da para tanto) ..... . Tratad de usar el foro y consultad los tutoriales disponibles, que muchas cosas solicitadas las podéis encontrar ya resueltos.
Creación de la Tabla
En una de nuestras bases de datos, creamos una tabla (con la consola de MySQL) con los siguientes atributos

Insertar una fila en la tabla
Gracias a la consola, podemos insertar la primera imagen directamente:

Al pulsar sobre la columna de la imagen, automáticamente podemos seleccionar un fichero a insertar.

Elegimos el desado

Como curiosidad de la foto, en las jardineras de mi ventana, podéis ver que tengo habitualmente plantados melones (hay que disfrutar el placer de las cosas simples) ;-)

Programa de recuperación de los datos
El mejor modo de entender como realizar la recuperación de los datos es leerse la propia especificación de JDBC que podéis encontrar en el Web de Sun: http://java.sun.com/products/jdbc/download.html

Necesitamos por tanto, un objeto de tipo BLOB para acceder a los datos. Volvemos a consultar la documentación, en este caso el API de JDBC http://java.sun.com/j2se/1.3/docs/api/java/sql/Blob.html
Y escribimos un código sencillo (no tengáis en cuenta el diseño ... ya que es lamentable .... pero no quiero complicar su seguimiento)
/*
* imagenbbdd.java
*
* @author Roberto Canales
* Ejemplo de manipulación de imagenes en Base de Datos
*/
import java.io.*;
import javax.sql.*;
import java.sql.*;
import java.awt.*;
public class CImagenbbdd {
public static void main(String[] args) {
CImagenbbdd nuevo = new CImagenbbdd();
nuevo.ejecuta();
}
public void depura(String param) {
System.out.println("Mensaje depuración: " + param);
}
public void ejecuta() {
long inicio = System.currentTimeMillis();
Connection con = getConexion();
long fin = System.currentTimeMillis() - inicio;
depura("El tiempo transcurrido en conectar es " + fin + " milisegundos");
InputStream imagenRecuperada = recuperaImagenBBDD(con);
guardaImagenEnDisco(imagenRecuperada);
fin = System.currentTimeMillis() - inicio;
depura("El tiempo transcurrido completo es " + fin + " milisegundos");
}
public void guardaImagenEnDisco(InputStream imagenBuffer)
{
try // (esto es practicamente una copia de ficheros clasica)
{
File fichero = new File("c:\\melones.jpg");
BufferedInputStream in = new BufferedInputStream(imagenBuffer);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fichero));
byte[] bytes = new byte[8096];
int len = 0;
depura("Copiamos el fichero");
while ( (len = in.read( bytes ))> 0 )
{
out.write( bytes, 0, len );
}
out.flush();
out.close();
in.close();
depura("Teminación del proceso con éxito");
}
catch(Exception e)
{
depura("Error al escribir en disco " + e.getMessage());
}
}
public Connection getConexion() {
Connection con = null;
try {
Driver d = (Driver)Class.forName("com.mysql.jdbc.Driver").newInstance();
depura("Recuperamos conexión");
con = DriverManager.getConnection("jdbc:mysql://localhost/tutoriales","","");
}
catch(Exception e) {
depura("Error al recuperar conexion " + e.toString());
return null;
}
return con;
}
public InputStream recuperaImagenBBDD(Connection con) {
try {
String consultaGenerada = "select * from imagenesbbdd limit 1";
depura("Ejecutamos Statement");
java.sql.Statement stmt = con.createStatement();
depura("Ejecutamos sentencia " + consultaGenerada);
ResultSet results = stmt.executeQuery(consultaGenerada);
results.next();
Blob campo = results.getBlob("imagen");
return campo.getBinaryStream();
}
catch(Exception e) {
depura("Error al recuperar el Stream");
}
return null;
}
}
|
Como curiosidad, podéis ver los tiempos:
Mensaje depuración: Recuperamos conexión Mensaje depuración: El tiempo transcurrido en conectar es 270 milisegundos Mensaje depuración: Ejecutamos Statement Mensaje depuración: Ejecutamos sentencia select * from imagenesbbdd limit 1 Mensaje depuración: Copiamos el fichero Mensaje depuración: Terminación del proceso con éxito Mensaje depuración: El tiempo transcurrido completo es 280 milisegundos |
Supongo que aquí os daréis cuenta de la necesidad de usar pooles de conexiones.
Podéis descargaros el código aquí
Otros enlaces de Interés
Podéis encontrar información valiosa sobre codificadores de distintos formatos en el siguiente enlace.
http://www.geocities.com/marcoschmidt.geo/java-image-coding.html
Aunque también os deberías fijar en las nuevas APIs y filtros para el procesamiento de imágenes que ya incorpora Java en las ultimas versiones.
http://javaalmanac.com/egs/javax.imageio/Graphic2File.html
Conclusiones
Como es de prever, escribir es similar ... ver setBinaryStream
void escribeImagenEnBBDD(Connection con)
{
try {
File fichero = new File("c:\\melones.jpg");
FileInputStream streamEntrada = new FileInputStream(fichero);
PreparedStatement pstmt = con.prepareStatement("insert into imagenesbbdd (nombre,imagen) values (?,?)");
pstmt.setString(1, "melones.jpg");
pstmt.setBinaryStream(2, streamEntrada, (int)fichero.length());
pstmt.executeUpdate();
pstmt.close();
streamEntrada.close();
}
catch(Exception e) {
depura("Error al escribir el Stream " + e.getMessage());
}
}
|
Lo bueno que tiene Java es lo fácil que nos hace el trabajo, con la impresionante librería de clases que proporciona. El arte es saber encontrar los recursos con velocidad.
Superados los problemas técnicos, solo nos quedan los problemas de negocio (capturar bien requisitos, hacer un análisis antes de lanzarlos a picar...) y la capacidad de hacer buenos diseños ..... cosa que poca gente tiene tiempo para poder hacer (y conocimientos debido a la falta de tiempo) .
A continuación puedes evaluarlo:
Fecha publicación: 2012-08-24-19:47:24
Autor: vancier
Fecha publicación: 2009-11-27-09:39:36
Autor: c3y43
muy bien sigue asi
Fecha publicación: 2009-11-10-02:15:31
Autor: camiloleal
Class.forName("org.sqlite.JDBC");
Connection conn= DriverManager.getConnection("jdbc:sqlite:bd.sqlite");
PreparedStatement ps = conn.prepareStatement("insert into tutabla(tuscampos) values (?)");
try {
conn.setAutoCommit(false);
File archivo = new File("rutadetuimagen");
FileInputStream f = new FileInputStream(archivo);
ps.setBinaryStream(1, f, (int) archivo.length());
ps.executeUpdate();
conn.commit();
} finally {
ps.close();
}
}
Fecha publicación: 2009-07-30-11:38:43
Autor:
Fecha publicación: 2009-07-08-02:23:32
Autor:
Fecha publicación: 2009-07-08-02:16:27
Autor:
Fecha publicación: 2008-05-05-10:48:39
Autor:
Fecha publicación: 2007-07-03-05:19:36
Autor:
Fecha publicación: 2006-09-15-09:00:45
Autor:











