Recuperar BLOB de ORACLE

    En uno de los articulos anteriores hablamos de como guardar un archivo (imagen, sonido, video ... ) en un base de datos ORACLE con PL SQL y los datos binarios, BLOB. Entonces prometimos explicar como recuperar y utlizar estos datos en una aplicación cliente.

    Como lo prometido es deuda ... aquí esta el articulo. Hemos seleccionado Java como lenguaje para desarrollar nuestra aplicación cliente. Como requisito previo debemos conocer el lenguaje de programación Java.

    Para la realización de este programa vamos a usar los siguientes packages:

  • java.io
  • java.sql
  • oracle.jdbc.driver

    Debido a que necesitamos el paquete de oracle.jdbc.driver vamos a necesitar incluir la librería classes12.jar  al ClassPath.

    El programa que vamos a realizar formará parte del package Devjoker.Oracle.Blob. Está compuesto de las siguientes clases:

  • GestorDeConexiones
  • RecuperadorBLOB
  • Main

    Las sentencias import que vamos a necesitar son las siguientes:


package Devjoker.Oracle.Blob;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.Blob;
import oracle.jdbc.driver.OracleConnection;
import oracle.jdbc.driver.OracleDriver;

    La primera clase que vamos a comentar es la clase GestorDeConexiones , encargada de establecer y gestionar las conexiones con ORACLE. Esta clase realiza las siguientes tareas:

  • El constructor GestorDeConexiones, que recibe el nombre de usuario de la base de datos y su clave de acceso.
  • conectar, método privado encargado de realizar la conexión.
  • closeConnection, cierra la conexion
  • getConnection, devuelve una referencia a la conexión abierta.

    El código de la clase GestorDeConexiones se muestra a continuación.La conexion se realiza a través del driver oci por lo que será necesario que tengamos instalado el cliente de Oracle. Si no disponemos del driver de Oracle podemos usar el driver thin. En todo caso la información de la url de conexión dependerá de nuestra configuración


class GestorDeConexiones
{
    private String user;
    private String password;
    private Connection conn = null;
    private boolean conectado = false;

    public  GestorDeConexiones(String usr, String pwd){
        user = usr;
        password = pwd;
    }

    public void closeConnection() throws SQLException{
        if (conectado)
            conn.close();
    }
   
    private void conectar() throws SQLException   {
       
        String url;

        DriverManager.registerDriver(new OracleDriver());
              
       // url = "jdbc:oracle:oci:@<TNS_NAME>";
       // url = "jdbc:oracle:thin:@<server>:<port=1521>:<SID>";

        url = "jdbc:oracle:oci:@ORACLEBD";
        conn = DriverManager.getConnection(url,user, password);
        System.out.println("Conexion correcta");
        conectado = true;
       
    }
   
    public Connection getConnection() throws SQLException
    {
        if (!conectado)
            conectar();
        return conn;
    }       

    La clase que realmente realiza el trabajo del programa es RecuperadorBLOB, que ejecuta una consulta a la base de datos y vuelca al sistema de archivos cliente el contenido de nuestro campo BLOB. El metodo RecuperarBLOB es estático por lo que no necesitaremos instanciar la clase, tan solo indicar el id del BLOB en la tabla y la ruta donde queramos guardar el resultado.

    Todo el trabajo se realiza en el método estático RecuperarBLOB, que ejecuta una consulta a la tabla "archivos" (creada y cargada en el artículo anterior), y con el resultado de la consulta guarda los datos en el sistema de archivos.

    La forma de ejecutar la consulta es la clásica de jdbc, es decir, construir la sql, crear un Statement y ejecutarlo para conseguir el ResultSet. Lo único que varia es almacenaremos el contenido del campo en una variable de tipo Blob (java.sql.Blob), y que con ella obtendremos el InputStream a través del método getBinaryStream(). A partir de ahí usaremos un FileOutputStream para guardar el archivo.

Nota:Cualquier archivo puede representarse como un array de bytes. Por esos usamos la variable byte buffer[].

    El código de la clase RecuperadorBLOB se muesta a continuación.


class RecuperadorBLOB
{
    public static void RecuperarBLOB
(Connection cn,  String idBLOB, String path)
    throws SQLException, IOException
    {
        FileOutputStream fos = null;
        Statement st = null;
        ResultSet rs = null;
        String sql ="select CO_ARCHIVO, " +
                    "       NOMBRE_ARCHIVO, " +
                    "       BIN, " +
                    "       FX_ALTA " +
                    "from archivos " +
                    "WHERE CO_ARCHIVO = '" + idBLOB + "' ";
     
        try{
            st = cn.createStatement();       
            rs = st.executeQuery(sql);
            if (rs.next())
            {               
                String pathname=
path + "\\" + rs.getString("NOMBRE_ARCHIVO") ;
                File file = new File(pathname);
                fos = new FileOutputStream(file);                   
                Blob bin = rs.getBlob("BIN");
                InputStream inStream = bin.getBinaryStream();
                int size = (int)bin.length();
                byte[] buffer = new byte[size];
                int length = -1;
                while ((length = inStream.read(buffer)) != -1)
                {
                  fos.write(buffer, 0, length);               
                }                                       
            }
        }
        catch (IOException ioe)
        {
            throw new IOException(ioe.getMessage());
        }
        finally
        {
            if (fos != null)
                fos.close();
            if (rs != null)
                rs.close();
            rs = null;
            st = null;       
        }       
    }
}

    Bien, pues con esto únicamente nos falta la clase Main, el punto de entrada del programa. Esta clase realiza las siguiente tareas:

  • Crea una instancia de GestorDeConexiones, y establece una conexion con nuestro servidor ORACLE.
  • Llama al método estático RecuperarBLOB de la clase RecuperadorBLOB, por tres veces (los tres archivos que, en mi caso, tengo guardos en la base de datos.
  • Cierra la conexion con la base de datos con el GestorDeConexiones.


public class Main {      
    public static void main(String[] args) {               
        System.out.println("Inicializando programa ...");
        Connection conn = null;
        GestorDeConexiones gc = null;
        try{
            gc = new GestorDeConexiones("app1", "password");
            conn = gc.getConnection();           
            String path = "c:\\javaout";
            RecuperadorBLOB.RecuperarBLOB(conn,"000001",path);
            RecuperadorBLOB.RecuperarBLOB(conn,"000002",path);
            RecuperadorBLOB.RecuperarBLOB(conn,"000003",path);                                           
        }
        catch (SQLException sqle) {
            System.out.println
("Error de acceso a BD:" + sqle.getMessage());
            sqle.printStackTrace();
        }
        catch (IOException ioe){
            System.out.println
("Error de acceso a disco:" + ioe.getMessage());
            ioe.printStackTrace();
        }
       
        try{
            if (gc != null && conn != null)
            gc.closeConnection();
        }
        catch (SQLException sqle)
        {
            System.out.println
("Error de acceso a BD:" + sqle.getMessage());
            sqle.printStackTrace();
            conn = null;
            gc = null;
        }
        System.out.println("Finalizando programa ...");
    }   
}

    Como habeis podido ver el código es bastante fácil, y el resultado ... bueno el resultado es este:


[Ampliar Imagen]

    El código completo es el que sigue a continuación:


/*
 * Main.java
 *
 * Created on 11 de septiembre de 2006, 23:33
 *

 */
package Devjoker.Oracle.Blob;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.File;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.Blob;
import oracle.jdbc.driver.OracleConnection;
import oracle.jdbc.driver.OracleDriver;
/**
 *
 * @author devjoker
 */
public class Main {       
    public static void main(String[] args) {               
        System.out.println("Inicializando programa ...");
        Connection conn = null;
        GestorDeConexiones gc = null;
        try{
            gc = new GestorDeConexiones("app1", "password");
            conn = gc.getConnection();           
            String path = "c:\\javaout";
            RecuperadorBLOB.RecuperarBLOB(conn,"000001",path);
            RecuperadorBLOB.RecuperarBLOB(conn,"000002",path);
            RecuperadorBLOB.RecuperarBLOB(conn,"000003",path);                                           
        }
        catch (SQLException sqle) {
            System.out.println
("Error de acceso a BD:" + sqle.getMessage());
            sqle.printStackTrace();
        }
        catch (IOException ioe){
            System.out.println
("Error de acceso a disco:" + ioe.getMessage());
            ioe.printStackTrace();
        }
       
        try{
            if (gc != null && conn != null)
            gc.closeConnection();
        }
        catch (SQLException sqle)
        {
            System.out.println
("Error de acceso a BD:" + sqle.getMessage());
            sqle.printStackTrace();
            conn = null;
            gc = null;
        }
        System.out.println("Finalizando programa ...");
    }   
}
class RecuperadorBLOB
{
    public static void RecuperarBLOB
(Connection cn,  String idBLOB, String path)
    throws SQLException, IOException
    {
        FileOutputStream fos = null;
        Statement st = null;
        ResultSet rs = null;
        String sql ="select CO_ARCHIVO, " +
                    "       NOMBRE_ARCHIVO, " +
                    "       BIN, " +
                    "       FX_ALTA " +
                    "from archivos " +
                    "WHERE CO_ARCHIVO = '" + idBLOB + "' ";
     
        try{
            st = cn.createStatement();       
            rs = st.executeQuery(sql);
            if (rs.next())
            {               
                String pathname=
path + "\\" + rs.getString("NOMBRE_ARCHIVO") ;
                File file = new File(pathname);
                fos = new FileOutputStream(file);                   
                Blob bin = rs.getBlob("BIN");
                InputStream inStream = bin.getBinaryStream();
                int size = (int)bin.length();
                byte[] buffer = new byte[size];
                int length = -1;
                while ((length = inStream.read(buffer)) != -1)
                {
                  fos.write(buffer, 0, length);               
                }                                       
            }
        }
        catch (IOException ioe)
        {
            throw new IOException(ioe.getMessage());
        }
        finally
        {
            if (fos != null)
                fos.close();
            if (rs != null)
                rs.close();
            rs = null;
            st = null;       
        }       
    }
}

class GestorDeConexiones
{
    private String user;
    private String password;
    private Connection conn = null;
    private boolean conectado = false;

    public  GestorDeConexiones(String usr, String pwd){
        user = usr;
        password = pwd;
    }

    public void closeConnection() throws SQLException{
        if (conectado)
            conn.close();
    }
   
    private void conectar() throws SQLException   {
       
        String url;              
        DriverManager.registerDriver(new OracleDriver());
       

       // url = "jdbc:oracle:oci:@<TNS_NAME>";
       // url = "jdbc:oracle:thin:@<server>:<port=1521>:<SID>";

        url = "jdbc:oracle:oci:@ORACLEBD";
        conn = DriverManager.getConnection(url,user, password);
        System.out.println("Conexion correcta");
        conectado = true;
       
    }
   
    public Connection getConnection() throws SQLException
    {
        if (!conectado)
            conectar();
        return conn;
    }       
}       

 Saludos, DJK

Pedro  Herrarte  Sánchez
Recuperar datos BLOB de ORACLE
Pedro Herrarte Sánchez

Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación. Posee mas de diez años de experiencia trabajando para las principales empresas de España. Es especialista en tecnologías .NET, entornos Web (ASP.NET, ASP.NET MVC,jQuery, HTML5), bases de datos (SQL Server y ORACLE) e integración de sistemas. Es experto en desarrollo (C#, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE). Pedro es MCP y MAP 2012, es fundador, diseñador y programador de www.devjoker.com..
Fecha de alta:19/09/2006
Última actualizacion:19/09/2006
Visitas totales:69795
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com