Guardar imagen en MySQL desde Java
Siguiendo con algo más de MySQL en java vamos a guardar una imagen en la base de datos desde una aplicación hecha en java. La idea es hacer la conexión básica siguiendo con los pasos acontinuación:
1. crear la conexión
2. Cargar la imagen la imagen a partir de FIeInputStream
3. Pasar la imagen a un flujo binario
4. Guardar la imagen
Lo primero es crear la conexión que comúnmente hacemos para conectarse con MySQL. Para ello necesitamos los datos elementales: host, nombre de la base de datos, usuario y la contraseña. Veamos como quedaría:
Class.forName("org.gjt.mm.mysql.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://host/nombre-base-de-datos", "usuario", "contrasena");
Preparamos la consulta a partir de la conexión creada, esta es una instruccion en SQL que el motor de mysql va a procesar, el único detalle que hay que tomar es que vamos a usar le signo ? (signo de interrogación) que sirve para informarle al objeto consulta que, ese valor será asigando mas adelante, pues primero hay que cargar la imagen y luego guardarla como bytes:
PreparedStatement ps = conn.prepareStatement("insert into fotos(id_foto, nombre, imagen) values (001, 'name', ?)");
Seguidamente hay que cargar el archivo con un objeto FileInputStream para que la imagen quede como un objeto de tipo File y por último pasar los bytes de la imagen al valor faltante de la consula:
File file = new File("logo.jpg");
FileInputStream fis = new FileInputStream(file);
ps = conn.prepareStatement(insertar_imagen);
ps.setBinaryStream(1, fis, (int) file.length());
En el código anterior se carga la imagen llamada logo.jpg que esta en nuestra pc. Con el objeto FileInputStream ya podemos procesar esa imagen para que al usar el método setBinaryStream() el objeto File que contiene la imagen pueda se convierta en un flujo de bytes que se almacenará en la base de datos.
Y por últmimo ejecutamos la consulta ya totalmente completa:
ps.executeUpdate(); conn.commit();
El código completo se debería ver algo así:
public class GuardarImagen {
public static void main(String[] args) throws Exception, IOException, SQLException {
Class.forName("org.gjt.mm.mysql.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/myjsp", "root", "adminadmin");
PreparedStatement ps = conn.prepareStatement("insert into fotos(id_foto, nombre, imagen) values (001, 'name', ?)");
try {
conn.setAutoCommit(false);
File file = new File("logo.jpg");
FileInputStream fis = new FileInputStream(file);
ps.setBinaryStream(1, fis, (int) file.length());
ps.executeUpdate();
conn.commit();
} finally {
ps.close();
}
}
}
Acá dejo el código completo y también la estructura de la tabla donde se guarda la imagen:
GuardarImagen.java y estructuraTabla
Tambíen puedes ver el tem de como cargar una imagen guardada en MySQL desde Java
35 comments
Trackbacks/Pingbacks
- Apuntes de programación » Cargar imagen guardada en MySQL desde java - [...] con el tema de cómo guardar una imagen en MySQL desde Java ahora vamos a explicar con un código ...
- [JAVA] Coneccion java a Sql 2005 server - P - [...] [...]
felicitacione todo muy claro
pero q pasa si tengo varias imagenes en mi base de datos y quiero usarlas en mi programa en java.
me gustaria q me dieran un ejemplo aunque sea simple (puede ser texto incluso) de como guardar en un array la informacion de la base de datos por q lo q tengo es q como q me sobreescribe los valores y solo me muestra la untima columna.
de antemano gracias.
@Seba
Hola seba,
creo que te entiendo, en todo caso ya me explicaras mejor.
Me parece que tu problema se debe a que no haces un “new” en el ciclo, por lo tanto solo le estas cambiando el valor a un mismo objeto cuando crees que estas haciendo uno nuevo, por esa razon solo te queda la informacion del ultimo registro. Por ejemplo, no es lo mismo:
Persona p = new Persona();
for (int i = 0; i < registros-base-de-datos; i++){
p.setNombre(registros-base-de-datos[i]);
arraylist.add(p);
}
a esto (lo correcto):
Persona p;
for (int i = 0; i < registros-base-de-datos; i++){
p = new Persona()
p.setNombre(registros-base-de-datos[i]);
arraylist.add(p);
}
pura vida
Hola!Muy bueno tu post quisiera que me ayudaras en algo. Yo quiero tomar el archivo de un directorio particular al momento de querer guardar, es decir, poder buscar la imágen o documento que deseo guardar en la base de datos y cargarla en el file. Esto sería desplegando una ventana donde busque el archivo en cuestión y lo cargue¿Cómo hago?
File file = new File(“RUTA DE ARCHIVO QUE SELECCIONE”);
Hola, para ellos usas un componente grafico llamado JFileChooser. Este componente es un buscar de archivos en tu disco duro, te carga el path del archivo seleccionado para que luego se le asignes al objeto File. Es algo asi:
JFileChooser chooser = new JFileChooser();
ExampleFileFilter filter = new ExampleFileFilter();
filter.addExtension(“jpg”);
filter.addExtension(“gif”);
filter.setDescription(“JPG & GIF Images”);
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(parent);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println(“You chose to open this file: ” +
chooser.getSelectedFile().getName());
}
Ya me contaras como te fue
como recupero luego de salvar una imagen jpg ?
es decir tengo que salvar las fotos de un grupo de pacientes y luego logicamente al consultar un paciente por el id que me traiga la foto.
Hola @Rafael,
Aca tienes un ejemplo de como cargar una imagen guardada en mysql desde java.
http://apuntes.delibertad.com/java/cargar-imagen-guardada-en-mysql-desde-java/
pura vida
Logré hacerlo delibertad gracias! ahora mi problema es que la ventana de carga de imágen no siempre me sale sobre la ventana desde donde la llamo sino que se posiciona detrás o en el escritorio inclusive. Definí un Jpanel en mi vista Padre para asignarsela en el showOpenDialog pero nada, sigue igual, estoy trabajando con ZK. Sólo pude hacer la definición lógica del JPanel ya que no me deja incluirlo como un elemento en el .zul, es decir definí JPanel = panel; pero la agregación de un elemento JPanel como parte de la vista no pude hacerlo. Cómo hago? Gracias!!!
Hola @Wolfmarel,
que bueno que te haya servidor, bueno mira, no entiendo concretamente tu problema. Podrias enviarme un “pantallazo” de tu problema, asi creo que seria mas facil comprender tu problema.
pura vida
Hola manix, disculpa mi desconocimiento, cómo hago para montar la imágen en este blog para mostrarte lo que comenté previamente?Gracias!
Hola @Wolfmarel.
Subela a un host gratuito como imageshack.us y que pongas el link aca, o que mandes la imagen adjuntada por correo al mail del blog que se encuentra en “acerca de”.
pura vida
Gracias manix por el interés. Ya logré resolverlo!! Usando Jframes y cargando la ruta de la imágen en un ImageIcon ;o)
me alegra mucho
Да уж, весело
solo tengo una duda con el codigo…
en postgres como tendria q declarar el tipo de dato
para mi columna
con que tipo de dato debo relacionarlo en posgrest
agradeceria mucho esta informacion
me ocurre un error al intentar almacenar la imagen:
java.lang.NullPointerException
qué podria ser??
mi codigo es asi:
Connection con = getConexion();
PreparedStatement ps = con.prepareStatement(“insert into fotos(id, nombre, imagen) values (001, ‘name’, ?)”);
try {
con.setAutoCommit(false);
File file = new File(“C:/Users/XoSeL/Pictures/cute_cat.jpg”);
FileInputStream fis = new FileInputStream(file);
ps.setBinaryStream(1, fis, (int) file.length());
ps.executeUpdate();
con.commit();
}
catch(Exception e) {
depura(“Error al escribir el Stream ” + e.getMessage());
} finally {
ps.close();
}
Hola @xosel,
No se ve algo que genere ese error a menos que el path de la imagen este mal.Has intentado usar un path relativo a tu proyecto?
pura vida
gracias @manix
he intentado de muchas formas y si parece como si no leyera el archivo de imagen..
en qué carpeta del proyecto debería estar la imagen para sólo poner su nombre??
@xosel,
Bueno, debes poner la imagen en la carpeta de tu proyecto. Si no sabes cual es la carpeta de tu proyecto ejecuta la siguiente linea para que el sistema te imprima el path:
System.getProperties("user.dir");En ese directorio es donde debes poner la imagen y llamarla unicamente con le nombre
Pura vida
he cambiado el código hasta quedar de la siguiente manera (un poco rústico, pero me ha servido para ver lo que ocurre cada paso):
Connection con = getConexion();
try{
//File file = new File("C:\\melones.txt");
depura(System.getProperty("user.dir"));
depura("intentando agregar archivo");
File file = new File ("C:\\melones.jpg");
if (file.exists()){
System.out.println("El fichero existe");}
else {
System.out.println("El fichero no existe");}
depura("intentando crear stream "+ file.toString());
InputStream fis = new FileInputStream(file);
depura("stream "+fis.toString());
//String imagenFich = new String ("C:/melones.jpg");
//fis=getImage(getDocumentBase(),imagenFich);
depura("intentando preparar statement");
PreparedStatement ps=con.prepareStatement("INSERT INTO fotos (id, nombre, imagen) values (1, 'melones', ?)");
depura("statement preparada");
ps.setBinaryStream(1, fis, (int) file.length());
ps.executeUpdate();
ps.close();
fis.close();
}catch (Exception e) {
depura("Error milochomil al escribir el Stream "+e.getMessage());
}
———
System.out me arroja los siguientes mensajes.
Mensaje depuración: Conexion establecida con Servidor
Mensaje depuración: C:\Sun\AppServer\domains\domain1\config
Mensaje depuración: intentando agregar archivo
El fichero existe
Mensaje depuración: intentando crear stream C:\melones.jpg
Mensaje depuración: stream java.io.FileInputStream@a14463
Mensaje depuración: intentando preparar statement
Mensaje depuración: Error milochomil al escribir el Stream null
supongo que esto significa quel el error está al preparar el statement.. que podría ser?
no sé si tenga que ver que intento agregar la imagen a un bd de sql server.. y el campo es de tipo imagen.. aunque creo q si fuera eso debería aparecer el error hasta ejecutar el método
executeUpdatey aparece enPrepareStatement..Pero mi tablas se llama fotos.. tiene un campo llave id, un campo varchar(50) nombre y un campo image imagen, todos están especificados para no permitir valores nulos.. entonces que estoy escribiendo mal??
@xosel,
Ya he probado guardando la imagen en campos de tipo Image y de tipo varbinary(max) y me dado resultado. En todo caso, hechale un vistazo a este post:
http://apuntes.delibertad.com/general/almacenar-imagen-en-sql-server-2005-desde-java/
Pura vida
Tengo una duda, yo quisiera implementar tu codigo en una aplicacion web, No se si tendria diferencias drasticas, por ejemplo, se puede cargar la imagen desde una tag de archivo de HTML, y se podria enviar en un formulario, para que los datos los reciba un servlet y procesarlo como lo procesas tu en tu aplicacion?
Gracias
Hola @crow ,
No deberia darte ningun problema, el cambio de codigo es minimo.
Pura vida
Hola. He tratado de hacer un proyecto utilizando el ejemplo que das pero al ejecutarlo em sale el siguiente error:
java.sql.SQLException: End of InputStream reached before satisfying length specified when InputStream was set
como puedo arreglarlo?
Hola @Yeison,
En ocaciones cuando intentamos guardar imagenes/archivos muy grandes, el campo de la base de datos no lo soporta, o no le fue especificado el total exacto del tamano de la imagen en el metodo:
ps.setBinaryStream(1, input-stream, archivo.length());
Por que no pones aca el estructura de tu tabla a la cual le tratas de hacer el insert? tambien pon el codigo de tu consulta y el tamano del archivo que tratas de guardar.
Pura vida
@manix
hola que tal aplique tu codigo en una jsp tanto el de insertar como el de consultar mi duda es la siguiente cuando consulto la imagen con tu codigo, primero se copia a algun directorio de la aplicacion y despues la mando a llamar con un , pero lo que quiero saber es si existe alguna manera de aparecer la imagen en el documento jsp y mostrarla junto con los datos de la consulta sin tener que copiarla a una carpeta del servidor al menos no de forma permanente.
Hola @lalok
Lo unico que se me ocurre es que uses Graphics2D y Graphics. Asi como php usa la libreia GD, vos como java puedes hacer uso de Graphics2D y Graphics con los bytes que tienes guardados en la basse de datos
Pura vida
que tal, me gustaria saber si hay una manera de obtener toda la ruta de donde se encuentra un archivo. Es que veo que en la instruccion
File file = new File(“logo.jpg”); este archivo debe estar en el path, lo que busco es alguna forma de obtener algo asi
File file = new File(“C:\…\logo.jpg”);
Saludos…
creo que me falto explicarme mejor en lo anterior jeje a lo que me referia es si hay algun metodo que me regrese toda la ruta donde se encuentra el archivo(“C:\…\logo.jpg”).
Para esto estoy utilizando el JFileChooser e imagino que el getSelectedFile() solo regresa el nombre del archivo, creo que ahora si mencione todos los detalles jeje
Saludos de nuevo
hola te felicito por tu algoritmo:
me preguntaba si este método de inserción tiene algún limite de tamaño para la imagen que se desea almacenar en la base de datos?.
saludos y gracias
Para guardar una imagen utilizo lo siguiente, pueden revisar el siguiente link
http://hwongu.blogspot.com/2008/05/muchas-veces-la-gente-se-pregunta-como.html
Y para obtener una imagen uso el siguiente método
http://hwongu.blogspot.com/2010/12/java-obtener-imagen-desde-base-de-datos.html
Excelente Codigo, gracias por el aporte
farfar por medio de jFileChooser.getPath() puedes obtener la ruta completa de tu archivo. espero ayudar saludos
bien post me sirvio de mucho tenia muchos problemas pero tooo me sale ok guardo la imagenen la Bd y luego las muestro en un Label !!!!:)