Gravando a imagem no banco de dados

Olá pessoal.

Eu sei que muita gente, pelo que eu andei pesquisando, é contra esse tipo de coisa mas infelizmente, não tem nenhuma solução para mim a não ser fazer isso. Mas eu preciso que seja salvo as figuras no banco de dados Postgre. Alguém sabe como fazer?? Todos os métodos que eu pesquisei, nenhum funcionou.

Detalhe. Estou usando applet, não sei se isso muda em alguma coisa pra fazer o método. Se alguém puder me ajudar, preciso disso meio urgente pois estou a 2 dias travado nisso :cry:

Valeu.

tb gostaria de saber so por curiosidade. qnd estudei sql vi q existe uma objeto image (se n me engano o nome) q salva imagens ate 2gb. eu dei 1 pesquisada no postgres 8.2.3 (o mais recente acho) e n vi esse objeto. acho no mssql deva ter. e ai quem ja usou? em que banco? como eh o insert nesse objetos?

Você pode fazer isso ou via component que já intercala essa funciolidade ou via response.binary , fiz isso injetando em um banco de dados Access 2000 e repliquei isso para front-end.

Já existe isso pronto na internet, no momento não me recordo sobre o componte que usei porém o caminho é PHP ou ASP…

Veja esse link se dá um help !!!

http://www.phpbuilder.com/columns/florian19991014.php3

Abraços

Crocodilo

eu sou a favor de armazenar imagens numa tabela de BD, sim!
só não apoio que seja na mesma tabela em que se vai realizar processos pesados.
sugiro, por exemplo, uma tabela de imagens tipo:

CREATE TABLE imagem (id INT, conteudo BLOB);

e depois fazer referencia a este ID na tabela relacionada.

CREATE TABLE cliente (id INT, nome VARCHAR(6), foto_imagem INT);

tipo “BLOB” pode ser usado no MYSQL e “bytea” (byte array) no PostgreSQL.
na inserção, usa-se o PreparedStatement com os métodos setBlob, setBinaryStream ou setBytes.

Valeu galera!! Mas eu preciso disso em Java mesmo. Eu usei o seguinte exemplo:

try { File file = new File("d:/www/leitor_digital/teste.jpg"); FileInputStream fis = new FileInputStream(file); PreparedStatement ps = con.conn.prepareStatement("INSERT INTO saude.cadastro_digital VALUES (?)"); ps.setBinaryStream(1, fis, file.length()); ps.executeUpdate(); ps.close(); fis.close(); JOptionPane.showMessageDialog(this,"Cadastro efetuado com sucesso!","Cadastro!",JOptionPane.INFORMATION_MESSAGE); } catch (SQLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }

E não funciona :frowning:

O que não funciona?

Tentaste fazer de acordo com : http://jdbc.postgresql.org/documentation/80/binary-data.html ?
A tabela saude.cadastro_digital, tem somente 1 campo?

Se somente falares que não está funcionando, não ajuda nem a ti nem a quem quiser te ajudar.

Até!

Certamente a solução existe, mas talvez tenha algo nas especificação mais modera aos invés de JAVA 1.4 veja na 1.5.

Bom…
Se souber de algo lhe aviso…, no momento não me lembro usando Java.

Abraço
Crocodilo

[quote=maquiavelbona]O que não funciona?

Tentaste fazer de acordo com : http://jdbc.postgresql.org/documentation/80/binary-data.html ?
A tabela saude.cadastro_digital, tem somente 1 campo?

Se somente falares que não está funcionando, não ajuda nem a ti nem a quem quiser te ajudar.

Até![/quote]

Sim para todas as perguntas que você fez. Desculpe, esqueci de colar o erro que dá. Deve ser alguma coisa boba porque senão ele nem axava a imagem hehe. Vejam:

[quote=console][quote]Exception in thread “AWT-EventQueue-3” java.lang.AbstractMethodError: org.postgresql.jdbc2.PreparedStatement.setBinaryStream(ILjava/io/InputStream;J)V
at cadastro_digital.btCadastrarActionPerformed(cadastro_digital.java:153)
at cadastro_digital.access$000(cadastro_digital.java:21)
at cadastro_digital$1.actionPerformed(cadastro_digital.java:105)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
[/quote][/quote]

Alguém suspeita o que pode ser?

Galera, fiz uns testes aqui no meu banco local. Existe duas funções que são perfeitas, funciona do jeitinho que eu quero, lo_import e lo_export. Acabei de fazer os testes e alem de facilitar muito e diminuir muito o código, é bem mais prático. Só tem um porém, precisa ser root para fazer isso. Se o cara não me passar o login e senha do root eu não vou conseguir funcionar. Alguém sabe como reverter isso?

Galera, não tem jeito!!! Consultei no fórum deles e eles me disseram que o template tem que ser salvo em bytes mesmo. Andei pesquisando e descdobri que esse esquema do postgre para adicionar foto pelo setBinaryStream, não funciona nas versões acima do 7.1.

Onde eu li isso o cara falou que só funciona usando o setBytes, mas tentei adaptar ao setBytes e vejam como ficou:

// Adds template to database and gets the ID. PreparedStatement stm = con.conn.prepareStatement("INSERT INTO saude.tabela_teste VALUES(?)"); ByteArrayInputStream input = new ByteArrayInputStream(util.template.getData()); stm.setBytes(1, util.template.getData()); stm.executeUpdate();

E o erro que retorna é:

[code]FastPath call returned ERROR: invalid large-object descriptor: 0

at org.postgresql.fastpath.Fastpath.fastpath(Fastpath.java:141)
at org.postgresql.fastpath.Fastpath.fastpath(Fastpath.java:191)
at org.postgresql.largeobject.LargeObject.write(LargeObject.java:173)
at org.postgresql.jdbc2.PreparedStatement.setBytes(PreparedStatement.java:300)
at cadastro_digital.btCadastrarActionPerformed(cadastro_digital.java:197)
at cadastro_digital.access$000(cadastro_digital.java:21)
at cadastro_digital$1.actionPerformed(cadastro_digital.java:113)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source) [/code]

Será que alguém poderia me ajudar?

Opa,

Na JAVA magazine numero 44 tem uma matéria que fala justamente disto, vc pode baixar o arquivo da revista aqui:

http://www.devmedia.com.br/javamagazine/download.asp

mas tem um porém no exemplo o cara nao implementa a inserção pois diz que é algo similar a recuperação da imagem, eu fiz um topico pra ver isso e varias pessoas deram ideias da uma olhada que talvez ajude, esse é o topico: http://www.guj.com.br/posts/list/60858.java#322836

t+

Depois posta ae se vc conseguiu, eu consegui, mas por causa do MVC eu fiz uma gambiarra, eu acho…

A proposito, sou de Maringá também

Que massa, tem outro cara aqui também que é de Maringá, só que eu esqueci o nome dele hehe.

Cara, na verdade eu consegui, só não sei se está de acordo com o que o pessoal da Griaule pede para salvar o template. Eu consegui com esse código:

[code]// Todos os LargeObject API chamados precisam estar com a transação bloqueada
con.conn.setAutoCommit(false);

                // Pega o Large Object Manager
                LargeObjectManager lobj = ((org.postgresql.Connection)con.conn).getLargeObjectAPI();

                // Cria um novo Large Object
                int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);

                // Abre o Large Object para escrita
                LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);

                // Abre o template
                ByteArrayInputStream fis = new ByteArrayInputStream(util.template.getData()); 

                // Copia os dados do template para o large object
                byte buf[] = new byte[2048];
                int s, tl = 0;

                while ((s = fis.read(buf, 0, 2048)) > 0) {
                    obj.write(buf, 0, s);
                    tl += s;
                }

                // Fecha o large object
                obj.close();

                // Cadastra no banco de dados
                PreparedStatement ps = con.conn.prepareStatement("INSERT INTO

saude.cadastro_digital VALUES (DEFAULT, ?, ?)");
ps.setInt(1, id_medico[cboMedico.getSelectedIndex()]);
ps.setInt(2, oid);
ps.executeUpdate();
ps.close();
fis.close();

                // Finaliza a transação
                con.conn.commit();[/code]

Ele salvou a figura, e fico massa o esquema porque ele salva qualquer coisa que estiver no seu PC e inclusive o template que é um objeto gerado pelo Grfinger. Eu extrai esses bytes do banco de dados e gerou um arquivo cheio de caracteres estranhos. Deve ser o template. Mas qualquer coisa eu testo com esse código.

Valeu.

segue um código testado no hsqldb

[code]
/*

  • Diversos.java
  • Created on 31 de Maio de 2007, 18:10
  • To change this template, choose Tools | Template Manager
  • and open the template in the editor.
    */

package teste;

import java.lang.;
import java.math.
;
import java.sql.;
import java.util.
;
import java.io.*;

/**
*

  • @author rico
    */
    public class Diversos {

    /**

    • Creates a new instance of Diversos
      */
      public Diversos() {
      }

    /**

    • @param args the command line arguments
      */
      public static void main(String[] args) {
      jdbc();
      }

    static void jdbc() {
    String driverClass = “org.hsqldb.jdbcDriver”;
    String url = “jdbc:hsqldb:mem:teste”;
    Connection con = null;
    try {
    Class.forName(driverClass);
    } catch (java.lang.ClassNotFoundException e) {
    System.out.println("ClassNotFound: "+e.getMessage());
    }
    try {
    con = DriverManager.getConnection(url,“sa”, “”);
    jdbc1(con);
    con.close();
    } catch(Exception ex) {
    System.out.println("Exception: "+ex.getMessage());
    ex.printStackTrace();
    }
    }

    static void jdbc1(Connection con) throws Exception {
    System.out.println("-- Criação tabela");
    String createTable =
    “CREATE TABLE imagem (nome VARCHAR(120), arquivo BINARY)”;
    Statement stmt = con.createStatement();
    stmt.execute(createTable);

     System.out.println("--Inserção imagem");
     String insertRow = "INSERT INTO imagem (nome, arquivo) VALUES (?, ?)";
     PreparedStatement pstmt = con.prepareStatement(insertRow);
     String nomeArquivo = "C:\\temp\\Dieckmann.jpg";
     File imagemFile = new File(nomeArquivo);
     pstmt.setString(1, imagemFile.getName());
     byte[] imagemArray = new byte[(int)imagemFile.length()];
     DataInputStream imagemStream =  new DataInputStream(new FileInputStream(imagemFile));
     imagemStream.readFully(imagemArray);
     imagemStream.close();
     pstmt.setBytes(2, imagemArray);
     pstmt.executeUpdate();
     System.out.println(imagemFile.getName());
     
     System.out.println("-- Select");
     pstmt.close();
     String selectImagem = "SELECT * FROM imagem";
     ResultSet rs = stmt.executeQuery(selectImagem);
     while (rs.next()) {
         String fileName = "C:\\temp\\_" + rs.getString("nome");           
         FileOutputStream fos = new FileOutputStream(fileName);
         
         /* Alternativa 1 - para arquivos muito grandes, economiza memória
         InputStream arquivoStream = rs.getBinaryStream("arquivo");            
         byte[] buffer = new byte[10];
         int nbytes = 0;
         while( (nbytes = arquivoStream.read(buffer)) != -1 )
             fos.write(buffer, 0, nbytes);
         arquivoStream.close();
          */
         
         // Alternativa 2 - Arquivos peguenos, como imagens e tal
         byte[] buffer = rs.getBytes("arquivo");
         fos.write(buffer);
         //
         
         fos.flush();
         fos.close();
     }
    

    }

}[/code]