Armazenar/Buscar fotos no banco oracle

Como faço para, a partir do html, inserir uma foto(JPG) em um banco e posteriormente poder mostrar essa foto para o usuário?
Obrigado!
Luiz Ronaldo

Heheehehehe…
Tentou procurar no Google?

[quote=“Luiz Ronaldo”]-inserir uma foto(JPG) em um banco…

  • mostrar essa foto…
    [/quote]

Procure BLOB, tanto na documentação do Oracle (Oracle 9i JDBC User’s Guide & Reference; Application Developer’s Guide - Large Objects (LOBs)) quanto na do JDBC. Além disso consulte o site otn.oracle.com, deve ter um monte de coisa interessante.

Luiz,

Por qeu você quer colocar as fotos no banco? Por que não mantêr elas em disco e apena guardar o nome do arquivo? Tem muito menos sobrecarga desnecessária :wink:

[]s

A minha necessidade é a seguinte: Estamos trabalhando em um catálogo de materiais e há a necessidade de ter uma foto(de exemplo) para cada tipo de material. Isso é para evitar que o usuário faça o pedido pela descrição e depois da compra efetuada fala: “Ha! Não era isso que eu queria”.
Esse catálogo vai ser acessado por usuários de todos os Estados(Estou em Brasília). É a primeira vez que vou trabalhar com imagens!
PS: Em três horas de pesquisa no Google, não achei algo que me desse condições de desenvolver uma servlet nesses moldes.
Obrigado!

A gravação de BLOBs depende e varia de banco para banco, mesmo usando Java.

Faça como o pcalcado sugeriu. Eu faria assim.

Pelo o que eu entedi eu deixaria uma máquina com todas as fotos armazenas e quando for mostrar a foto, a mostro de acordo com o código armazenado no banco certo?
Isso resolveria momentaneamente, mas está previsto um novo projeto, na qual será feito um levantamento de carga patrimonial e o detentor da carga, quando julgar necessário, tira uma foto de uma mesa, por exemplo, e essa foto será usada para mostrar o estado do bem. A única informação que tenho é essa foto terá no max 50 kb.
Mesmo que o Oracle, que é o banco que estou usando, me dê uma resposta lenta, terei que fazer essa implementação. Se a chefia não gostar provalmente desista da idéia de armazenar as fotos no banco.

Ué, aidna não etnendi: por que você tem que colcoar a foto no banco? Da mesma maneira que vc guarda a foto nele (na verdade, masi facilmente), voce coloca no disco sem a itnerferência do oracle. Pede rpa ele te gerar uma chave aleatória e nomeia o arquivo com isso, pronto, seus problemas se acabaram-se!!

[]s

Use componente Java para FTP se o seu caso for fazer FTP via o site.

O porque da foto no banco:
O Serviço de Material fica em Brasília, para que um usuário, em qualquer parte do Brasil, faça o pedido de um material, basta ele acessar o sistema e digitar o nome genérico do material. Clicar na foto que lhe será mostrado, que, por sugestão, estará armazenada em uma máquina em Brasília(Não no banco).
Mas anualmente é feito, também em todas as unidades dos Estados, um levantamento de carga patrimonial feito com um PalmOS com leitura de código de barras. No momento que um material é “pistolado”, o Palm fornece todas as informações do bem, e foto inclusive(esperado). Nesta ocasião, cada material poderá ser fotografado para atualização do seu estado físico(em condições de uso, danificado etc). Como são 28 unidades gestoras que farão esse levantamento, o controle dessas fotos ficará em Brasília.
Repito: Não tenho experiência suficiente para bolar o melhor sistema para controlar essa parafernália toda.
Não fiquem constrangidos de começar do ABCD…
Muito obrigado!

É só vc jogar esse arquivo numa área de disco que seja pública, por exemplo, dentro da pasta do seu projeto, que vc pode acessar como: http://www.seusite.com.br/imagens/prod00001.jpg.

Parece que as fotos são bem pequenas, não há problemas em pô-las no banco. (Antigamente você precisava se preocupar com essas coisas, hoje em dia o banco lida com elas “numa boa”.)
Por acaso você se preocupava com essas coisas quando usava campos MEMO no Clipper ou no dBase? Da mesma maneira não se incomode com imagens pequenas, pode usar BLOB sem problema.
Você precisa ter uma servlet (não um JSP) para mostrar essas fotos (coisa boba - faz uma consulta na base, puxa o BLOB, seta o content-type para “image/jpeg” ou “image/gif” ou “image/png”, dependendo do tipo original da imagem, e envia os dados de volta para o usuário), e uma classe de upload (pode ser a que vem com o Struts, ou a que tem com o jakarta.apache.org Commons Upload.)
Só lembrar de você ter uma coluna na tabela contendo o tipo da imagem, porque embora isso possa ser determinado examinando-se os bytes iniciais da imagem, acho mais fácil para quem está desenvolvendo deixar isso explicitamente escrito em uma coluna da tabela. (É óbvio que sou “issperrto” e ia checar os bytes iniciais, mas ia ter de escrever uma rotina só para checar o tipo da imagem… É mais fácil guardar a extensão do arquivo original.)

Existe algum motivo real para se colcoar imagens em um banco? Facildiade? Rapidez? Economia?

Independente de que banco estamos falando, ele vai gerar um overhead ao anexar colcoar seus formatos de dados próprios aos bytes do arquivo. No fim das contas você vai ter um arquivão quando podia ter um arquivinho, não vai poder suar muito SQL em cima dele… enfim. Para que?

[]s

E para levar em conta o fato que a foto é algo “quase-estático”, conforme o “web container” pode-se configurar o servlet para que sua saída seja “cached”, ou seja, se alguém acessou o servlet com determinado parâmetro (correspondente a uma determinada foto), se esse servlet for chamado novamente com o mesmo parâmetro (ou seja, vai puxar a mesma foto) dentro de um determinado período (digamos 1 hora ou 1 dia), em vez de consultar novamente a base, ele puxa um valor “cached” (ou seja, ele guarda o valor anterior) e isso acelera o acesso ao seu sistema. (Obviamente se você alterou a foto no banco então a foto que você vai receber no browser vai ser a foto antiga, até que passe aquele tempo preconfigurado no servlet, portanto essa configuração não é para ser usada sem pensar um pouco.)

Um filesystem descente tem a mesma funcionalidade e é bem mais simples :wink:

[]s

Normalmente em bases modernas BLOBs são armazenados da seguinte maneira:

  • Se for pequeno (digamos 4K no máximo, obviamente depende do seu banco) o BLOB é armazenado como sendo uma coluna grande, como se fosse um VARCHAR.

  • Se for grande, o BLOB é armazenado em um espaço separado (aí em consultas normais, como joins e outras coisas mais, o BLOB não fica “atrapalhando”). Pode ser até que o banco armazene o BLOB em um arquivo separado para cada BLOB muito grande. Mas aí você deixa o abacaxi para o banco descascar (de ficar controlando milhares de arquivos, e fazer corresponder o arquivo ao seu registro na tabela), não para você.

  • O que pode dar problemas, na verdade, é se o BLOB participa de transações ou não, porque isso altera o espaço necessário para o log de transações e o tempo de atualização/modificação/deleção. Isso depende um pouco do seu banco. (Tem bancos onde os BLOBs não participam do log de transações, mas isso você deve conferir na documentação.)

  • Outra coisa que pode dar problemas é se você precisa de fazer o backup do seu banco muito rapidamente, e você acha que seria melhor backupear as fotos separadamente dos registros das suas tabelas. (acho que em particular deve dar confusão no seu sistema se você fizer os backups em lugares diferentes, pode dar alguma inconsistência).

  • Os bancos de dados modernos são muito usados para armazenamento eletrônico de documentos (por exemplo, se não me engano o IBM Content Manager requer o DB2), e em muitos casos são usadas estruturas de dados especiais, mas mais para acelerar a indexação, que para deixar os dados em arquivos separados, fora do banco.

  • Só faça uma coisinha… No caso específico do Oracle, cheque se seu driver JDBC é o mais novo possível para a sua versão do Oracle, e se ele está conseguindo escrever ou ler dados com mais de 8KB no banco. (Teste seu sistema com fotos grandes também).
    Algumas versões não conseguem fazer isso direito com BLOBs, não sei exatamente porquê.

Olá

A idéia do thingol de usar blob para o caso de imagens de um tamanho tal que não sacrifiquem a performance da base de dados tem a vantagem de unificar os processos de backup. Becapeou a base, salvou todas as imagens.

Mas em compensação a idéia do Phillip tem a vantagem de se poder usar scp ou ftp (de preferência scp) para incluir as imagens no file-system e um processo simples no servidor para perceber novas imagens. A idéia pode ser aprimorada para subir muitas imagens juntas com tar e no servidor serem abertas.

A melhor solução será dada por quem realmente está ganhando dinheiro e tendo a responsabilidade no projeto. Em geral não gosto muito da solução de grandes blobs na base a menos que não haja perigo de esgotar recursos de hardware. Concordo com o Thingol que com imagens pequenas, se pode usar as facilidades do engine da base que nem existem no file system sem programar.

[]s
Luca

Colocar em blob vai fazer com que a aplicacao use mais memoria / processamento, ja que voce tem que ler a imagem, gravar no banco, ler do banco, jogar para o usuario… Gravando a imagem em disco e deixando no banco somente o nome da imagem, em um campo texto, costuma ser muito mais pratico.

Voce pode fazer como o daniel disse, colocando a imagem em uma area acessivel via web ou, caso nao deseje isso, ainda assim pode ler a imagem do disco e armazenar em algum objeto, da mesma forma como iria fazer se fosse ler do banco de dados.

O ponto do Luca sobre backup eh um bom argumento, mas nada que nao possa ser facilmente contornado.

Mas, se ainda assim vc achar que deve gravar as imagens no banco, simplesmente crie uma tabela com um campo blob e outro campo com o nome / id da imagem, e use esse campo para buscas.

Rafaelk

Era isso que eu ia sugerir (as tabelas são relacionadas 1 x 1, mas você pode fazer backups separados, e na maior parte do tempo você pode trabalhar só com a tabela sem as fotos.).

Vou desenvolver, inicialmente, colocando as fotos em uma pasta pública e para fins de aprendizado farei em seguida usando o banco.
Quero deixar registrado que a ajuda de vcs foi acima das minhas expectativas.
Agradeço a todos. Muito Obrigado!