31.12. Exemplo de utilização de BLOB no JDBC

Nota: Esta seção foi escrita pelo tradutor, não fazendo parte do manual original.

Este exemplo serve para testar o acesso aos objetos grandes pelo driver JDBC, usando tanto a API proprietária quanto a API padrão. É fornecido junto com a distribuição do código fonte do PostgreSQL, no arquivo src/interfaces/jdbc/example/blobtest.java. Além da tradução, foram introduzidas pequenas alterações com relação ao código original.

No Fedora Core 2 foi utilizado "export CLASSPATH=/usr/share/java/pg74.1jdbc3.jar:." para executar o programa a partir da linha de comando, e "/usr/share/java/pg74.1jdbc3.jar" na configuração de Bibliotecas do Usuário do BlueJ para o programa ser executado nesta IDE.

import java.io.*;
import java.sql.*;
import org.postgresql.largeobject.*;

/*
 * Este teste tem por objetivo criar um BLOB no banco de dados, e depois
 * ler o mesmo.
 * 
 * Foi utilizada a imagem "/usr/share/backgrounds/images/dragonfly.jpg"
 * do Fedora Core 2 para fazer o teste. Deve ser substituída por outra
 * caso esta imagem não exista no sistema.
 *
 * Nota importante: Observe que é importado o pacote org.postgresql.largeobject,
 * mas não é importado o pacote org.postgresql. A razão disto é que a importação
 * deste último confunde o javac (existe conflito entre nomes de classes em
 * org.postgresql.* e java.sql.*). Isto não causa nenhum problema, desde que
 * o código não importe org.postgresql.
 *
 * Nas circustâncias normais, o código que utiliza qualquer driver de jdbc
 * somente precisa importar java.sql e, portanto, isto não é um problema.
 *
 * Somente quando são utilizadas funcionalidades não-jdbc é que isto deve
 * ser levado em consideração.
 *
 */

public class BlobTest
{
    Connection db;
    Statement s;
    LargeObjectManager lobj;
    String strImagem = "/usr/share/backgrounds/images/dragonfly.jpg";
    
    public void go() throws ClassNotFoundException, FileNotFoundException,
                       IOException, SQLException
    {
        // Banco de dados, usuário e senha igual a "teste"
        // CREATE USER teste WITH password 'teste';
        // CREATE DATABASE teste WITH OWNER teste ENCODING 'LATIN1';
        String url = "jdbc:postgresql://localhost/teste?charSet=LATIN1";
        String usr = "teste";
        String pwd = "teste";

        // Carregar o driver
        Class.forName("org.postgresql.Driver");

        // Conectar com o servidor de banco de dados
        System.out.println("Conectando ao banco de dados\nURL = " + url);
        db = DriverManager.getConnection(url, usr, pwd);

        // Necessário para todas as chamadas a LargeObject
        System.out.println("Conectado... Primeiro desabilitar autoCommit()");
        db.setAutoCommit(false);

        System.out.println("Criando a declaração");
        s = db.createStatement();

        // Executar os testes utilizando a API LargeObject do PostgreSQL.
        // NOTA: Os métodos mostrados neste exemplo NÃO são JDBC, mas são
        // implementações de chamadas encontradas na libpq. A menos que
        // estas funcionalidades sejam necessárias, veja nos testes de
        // JDBC como acessar os BLOBS.
        ownapi();

        // Fechar o banco de dados
        System.out.println("Fechando a conexão");
        s.close();
        db.close();
    }
    /*
     * Esta é uma extensão do JDBC única do PostgreSQL. É trazido um
     * objeto PGlobj, que fornece as funcionalidades da API LargeObject
     * PostgreSQL.
     */
    public void ownapi() throws FileNotFoundException, IOException, SQLException
    {
        System.out.println("\n--------------------------------------" +
                           "\nTeste da API LargeObject do PostgreSQL" + 
                           "\n--------------------------------------");

        // Internamente o driver JDBC fornece métodos para acessar
        // objetos grandes em conformidade com a especificação do
        // JDBC, entretanto os métodos disponíveis unicamente para
        // o PostgreSQL tornam o acesso um pouco mais fácil.
        System.out.println("Obtendo acesso à API LargeObject");
        lobj = ((org.postgresql.PGConnection)db).getLargeObjectAPI();

        int oid = ownapi_test1();
        ownapi_test2(oid);

        // Chamar o teste jdbc2api
        jdbc2api(oid);

        // Remover o Objeto Grande
        ownapi_test3(oid);
        System.out.println("\n\nOID=" + oid);
    }

    private int ownapi_test1() throws FileNotFoundException, IOException, SQLException
    {
        System.out.println("Teste 1 - Criação do objeto grande\n");

        // O teste 1 se destina a criar o objeto grande.
        // A criação é feita utilizado o método "create".
        System.out.println("Criando o Objeto Grande");
        int oid = lobj.create(LargeObjectManager.READ | LargeObjectManager.WRITE);
        DriverManager.println("OID do Objeto Grande criado=" + oid);

        LargeObject obj = lobj.open(oid, LargeObjectManager.WRITE);
        DriverManager.println("got large object obj=" + obj);

        // Abrir o arquivo de teste
        System.out.println("Abrindo o arquivo de teste");
        FileInputStream fis = new FileInputStream(strImagem);

        // copiar os dados
        System.out.println("Copiando o arquivo para o objeto grande");
        byte buf[] = new byte[2048];
        int s, tl = 0;
        while ((s = fis.read(buf, 0, 2048)) > 0)
        {
            System.out.println("Tamanho do bloco=" + s + " deslocamento=" + tl);
            obj.write(buf, 0, s);
            tl += s;
        }
        DriverManager.println("Copied " + tl + " bytes");

        // Fechar o objeto
        System.out.println("Fechando o objeto");
        obj.close();

        return oid;
    }

    private void ownapi_test2(int oid)
        throws FileNotFoundException, IOException, SQLException
    {
        System.out.println("Teste 2 - Ler o objeto grande e salvar num arquivo\n");

        // Abrir o objeto grande
        System.out.println("Abrindo o objeto grande " + oid);
        LargeObject obj = lobj.open(oid, LargeObjectManager.READ);
        DriverManager.println("got obj=" + obj);

        // Abrir um arquivo de teste
        System.out.println("Abrindo o objeto de destino do teste");
        FileOutputStream fos = new FileOutputStream("blob_teste_saida");

        // Copiar os dados
        System.out.println("Copiando o objeto grande para o arquivo");
        byte buf[] = new byte[512];
        int s = obj.size();
        int tl = 0;
        while (s > 0)
        {
            int rs = buf.length;
            if (s < rs)
                rs = s;
            obj.read(buf, 0, rs);
            fos.write(buf, 0, rs);
            tl += rs;
            s -= rs;
        }
        DriverManager.println("Copied " + tl + "/" + obj.size() + " bytes");

        // Fechar o objeto
        System.out.println("Fechando o objeto");
        obj.close();
    }

    private void ownapi_test3(int oid) throws SQLException
    {
        System.out.println("Teste 3 - Remoção do objeto grande\n");

        // Remover o objeto grande
        System.out.println("Removendo o objeto grande " + oid);
        lobj.unlink(oid);
    }

    // Testar a interface BLOB da especificação JDBC 2.0
    public void jdbc2api(int oid) throws SQLException, IOException
    {
        System.out.println("Testando a interface JDBC2:");
        jdbc2api_cleanup();

        System.out.println("Criando um BLOB no objeto grande " + oid);
        s.executeUpdate("create table basic (a oid)");

        System.out.println("Inserindo a linha");
        s.executeUpdate("insert into basic values (" + oid + ")");

        System.out.println("Selecionando a linha");
        ResultSet rs = s.executeQuery("select a from basic");
        if (rs != null)
        {
            while (rs.next())
            {
                System.out.println("Buscando o BLOB");
                Blob b = rs.getBlob("a");
                System.out.println("Tamanho do BLOB = " + b.length());
                System.out.println("Caracteres 400-500:");
                System.out.write(b.getBytes(400, 100));
                System.out.println();
            }
            rs.close();
        }

        System.out.println("Limpeza");
        jdbc2api_cleanup();
    }

    private void jdbc2api_cleanup() throws SQLException
    {
        db.setAutoCommit(true);
        try
        {
           s.executeUpdate("drop table basic");
        }
        catch (Exception ex)
        {
             // Ignorar todos os erros
        }
        db.setAutoCommit(false);
    }

    public static void main(String args[])
    {
        System.out.println("PostgreSQL - Teste de BLOB v7.0 rev 1\n");

        // Executar os testes
        try
        {
            BlobTest blobtest = new BlobTest();
            blobtest.go();
        }
        catch (Exception ex)
        {
             System.err.println("Exceção capturada.\n" + ex);
             ex.printStackTrace();
         }
    }
}
SourceForge.net Logo