[RESOLVIDO] Como salvar Imagens no Banco ?

Olá pessoal, eu queria registrar uma imagem no banco, no caso eu estou usando o Oracle 10g.

Ou vi falar de um Tipo BLOB, mas o Controller não está conseguindo pegar o arquivo como parametro.

Qual a vantagem do BLOB?

E se salvar o caminho da foto e colocar como String, qual caminho eu colocaria, o caminho da pasta no servidor ou da pasta do usuário ?

Meu JSP

<h2>Página de Registro das Contas</h2> <form action="efetuaRegistro" method="post"> Nome : <input type="text" name="nome" /> <br /> Sobrenome: <input type="text" name="sobrenome" /> <br /> Login: <input type="text" name="login" /> <br /> Senha: <input type="text" name="senha" /> <br /> Imagem: <input type="file" name="foto" /> <input type="submit" value="Entrar nas contas" /> </form>

Meu Controller :

` @RequestMapping(value="/efetuaRegistro")
public String efetuaRegistro(String login , String senha , String nome , String sobrenome, BLOB imagem ) throws SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException, SystemException{

	UsuarioDao usuariodao = new UsuarioDao();
	
	usuariodao.adiciona(login,senha,nome,sobrenome, imagem);
	
	return "usuarioLogado/usuarioLogado";
}`

Meu Usuario :

@Basic @Lob @Column(name="USUA_FOTO") BLOB imagem;

Meu UsuarioDao

`@Repository
public class UsuarioDao {

public void adiciona(String login , String senha , String nome , String sobrenome, BLOB imagem) throws SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException, SystemException{

	
	Usuario usuario = new Usuario();
	
	usuario.setNome(nome);		

	usuario.setSobrenome(sobrenome);
	
	usuario.setImagem(imagem);
				
	usuario.setLogin(login);
	
	usuario.setSenha(senha);
	
	usuario.setHabilitado(true);
	
	SessionFactory factory = new Configuration().configure().buildSessionFactory();
	
	Session session = factory.openSession();
	
	session.beginTransaction();
	
	session.save(usuario);
	
	session.getTransaction().commit();
	
	session.close();

	
}`

Boa tarde valter,

o tipo blob é tipo de dados que aceita você armazenar um arquivo binário no banco de dados, isso deixa o banco mais pesado com o tempo e vai consumir muito recurso do mesmo, outra forma é como você falou, salvar o nome da imagem juntamente com sua extensão, apenas isso, exemplo:

imagem.jpg
imagem.png
imagem.gig

e na sua aplicação você joga essas imagens em alguma pasta do servidor da sua aplicação, dentro do seu projeto, ou não, tanto faz isso, você pode converte-la em base64, pegar essa string do base64 passar para seu back-end, converte-la novamente em binário e salvar na pasta, ou enviar como binário mesmo e salvar a imagem na pasta, sendo o mais indicado ao meu ver você seguir salvando apenas o nome da imagem no banco, na sua base de dados seria interessante ter alguma tabela de paremetrização, para quando fosse recuperar a imagem e salva-la em um diretório especifico, ficando dinâmico e não hard-code.

exemplo:

String diretorio = "C:\projeto\imagens";
String nomeImagem = "imagem.png";
String imagem = diretorio + nomeImagem;

seria interessante que a variável diretorio fosse dinamica, obtendo seu valor da consulta de algum arquivo de paremetrização, ou via banco de dados que é mais indicado, ao final disso teria sua aplicação sempre preparada para salvar imagens em qualquer lugar.

Boa tarde Felipe,

Primeiramente, obrigado pelo suporte, mas me restaram umas dúvidas :

Como eu faria o procedimento para pegar a foto e envia-la para o banco ?

Mandaria o Controlador pegar byte[] imagem ou File imagem?

Pegaria o nome dessa imagem mandava pra o banco como String, salvava essa imagem em um diretório no servidor…

E quando fosse mostrar faria src=“diretório+imagem” , onde a imagem viria do banco…

Porém o seguinte, eu poderia botar o nome da imagem o ID do usuário. Porém e se ele quisesse alterar imagem? Eu teria que sobrescrever a imagem somente no servidor é isso ?

Boa noite valter, respondendo as suas dúvidas:

Como eu faria o procedimento para pegar a foto e envia-la para o banco ?
No seu JSP crie um botão para aceitar um arquivo

<form method="POST" action="<c:url value='/upload' />"
    enctype="multipart/form-data">

    Sua Imagem: <input type="file" name="file" />
    <input type="submit" value="upload" />

</form>

Mandaria o Controlador pegar byte[] imagem ou File imagem?
No seu controller você receberá um File

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String handleFormUpload( @RequestParam("file") MultipartFile file) throws IOException{
    if (!file.isEmpty()) {
            try {
    	   File novaImagem = new File(caminhoImagem, nomeImagem);
    	   OutputStream os = new FileOutputStream(novaImagem);
               os.write(Files.readAllBytes(imagem.toPath()));
    	   os.close();
	} catch (IOException e) {
	   
	}
     }  
}

Pegaria o nome dessa imagem mandava pra o banco como String, salvava essa imagem em um diretório no servidor…
Você pode enviar a imagem unicamente como arquivo, no caso ela vai como binário para seu back-end (seu controller), ou converter esse binário em base64 onde você obtem uma String que é o resultado da conversão do seu arquivo da imagem em binário para base64, isso é um modo, no exemplo que citei acima envio como File mesmo, binário.

E quando fosse mostrar faria src=“diretório+imagem” , onde a imagem viria do banco…
Cada imagem a ser salva em um diretório que você determinou deve ter um identificador único, no caso seria interessante juntar ao nome da imagem um hash(md5, sha1, etc) a cada upload de uma imagem, para recuperar a imagem você iria ter o nome dela que foi salvo no banco de dados, em um campo Varchar, e iria varrer o diretório de imagens, onde as imagens estão salvas, e bater o nome da imagem que está no banco com o nome das imagens do diretório, assim recuperando-a.
seu controller quando enviar um objeto de response, deve ter um atributo definido com o resultado da imagem, url+nomeimage,

ficando exatemente como você falou: <img src="<%=controller.getImage()%>" />

Porém o seguinte, eu poderia botar o nome da imagem o ID do usuário. Porém e se ele quisesse alterar imagem? Eu teria que sobrescrever a imagem somente no servidor é isso ?
Se ele quiser alterar a imagem, você da update no respectivo campo no banco de dados que contém o nome da imagem antiga, ficando com o novo nome, o processo de salvar é o mesmo, e caso queira pode varrer o diretório e deletar a imagem antiga.

caso ainda tenha dúvidas, dê uma pesquisada em upload de imagem com Spring-mvc que é o que você está usando, correto?

abraços!

3 curtidas

Você me esclareceu perfeitamente, MUITÍSSIMO OBRIGADO, e sim estou usando Spring-mvc !