Categorías del Tutorial

icono_twiter icono LinkedIn icono Facebook Icono Xing
Roberto Canales Mora

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:

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í

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2004-05-22

Tutorial visitado 84.904 veces Descargar en PDF
New Page 2

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) .

Sobre el Autor ..

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL:

Fecha publicación: 2012-08-24-19:47:24

Autor: vancier

Muchas gracias por el tutorial....Super util y lo mejor, se entiende todo :]

Fecha publicación: 2009-11-27-09:39:36

Autor: c3y43

Ante todo felicitarte por este magnifico tutorial ya que es muy dificil encotrar en la red informacion asi y bien detallada, no como otros que te ponen un super codigo tal vez copiado de sun y se las dan de que saben mucho.
muy bien sigue asi

Fecha publicación: 2009-11-10-02:15:31

Autor: camiloleal

public static void main(String[] args) throws Exception, IOException, SQLException {
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:

[claudia] Hola Gracias por tu valioso aporte! Por Favor me podrias aclarar como hacer para incluir directamente las imagenes en la Base de Datos, Yo estulizando como cliente a SQL Manager 2005. Ya tengo en mi tabla un campo imagen de tipo longblob, pero no encuentro como insertar alli las imagenes. Agradecida por la atención prestada. y en espera de pronta respuesta.

Fecha publicación: 2009-07-08-02:23:32

Autor:

[rcanales] Hola kaleg: Normalmente los recursos gráficos no se guardan en la base de datos, solo el enlace a un sistema de ficheros. De todos modos, reproduce el tutorial (aunque ojo que tiene 5 años y algo podría haber cambiado...)

Fecha publicación: 2009-07-08-02:16:27

Autor:

[kaleg] hola a todos este ejemplo es muy interesante voy a descargarme el codigo yo estoy haciendo un pequeño proyecto en jsp en el cual tengo una base de datos con un campo tipo blob en el cual tengo que agregar los datos de una persona con su respectiva foto que se almacene en la bd. Como podria utilizar este codigo ya que no se como hacerlo?, si pudieran darme una idea como usarlo. voy a buscar si hay algo mas sobre esto si pueden ayudarme en algo de antemano gracias y agradecido por este codigo. espero que puedan contactarse...gracias.

Fecha publicación: 2008-05-05-10:48:39

Autor:

[Galo] Este tutorial a sido de gran ayuda, te agradezco, muy bueno realmente. Me ayudaría aun más si pudiera realizar la selección con el JFileChooser. Gracias.

Fecha publicación: 2007-07-03-05:19:36

Autor:

[rodrigo] lo probare

Fecha publicación: 2006-09-15-09:00:45

Autor:

[Luisa Fernanda Barro] Hola!! Muy valioso este tutorial de manejo de imagenes...me simplifico muchisimo el trabajo, sin embargo sería bueno incluir como manejar el path para insertar imagen con un JFileChooser. Excelente ayuda ...Gracias