Arquivo para J2EE

How to save and read Oracle Blob from java

I wanted to save and load large binary objects (BLOB) from Oralce database and get into array of bytes in Java.

The access to database cound’t be done directly to the table, it uses a stored procedure that insert’s the record and returns then primary key of the table.

After long research, I’m giving back to the community…

I use an object UtilsDB.getDataSource().getConnection(); to get a connection from JNDI … bue the important is you have some way to get the database connection.

Atention: This doesn’t work if you’re using ojdbc14-9.0.2.0.0.jar. I had to change this jar to ojdbc14-10.2.0.3.0.jar, then it worked ok.

So, to save a chunck of bytes (a PDF file, for example) into a Dabatase

public BigDecimal saveBlobIntoDatabase (byte [] ficheiro,
String nomFicheiro,
String nomDirectoria)
throws SQLException, IOException {

Connection oracleConnection = UtilsDB.getDataSource().getConnection();

CallableStatement stmt = oracleConnection.prepareCall(DBResources.F_GRAVA_BLOB_BD);

BLOB blob = BLOB.createTemporary(oracleConnection, false, BLOB.DURATION_SESSION);

OutputStream outputStream = blob.setBinaryStream(0L);
InputStream inputStream = new ByteArrayInputStream(ficheiro);
byte[] buffer = new byte[blob.getBufferSize()];
int byteread = 0;
while ((byteread = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, byteread);
}
outputStream.close();
inputStream.close();

BigDecimal numFicheiro = new BigDecimal(0);
stmt.registerOutParameter(1, OracleTypes.NUMBER);
stmt.setBlob(2, blob);
stmt.setString(3, nomFicheiro);
stmt.setString(4, nomDirectoria);
stmt.execute();
numFicheiro = stmt.getBigDecimal(1);
stmt.close();

return numFicheiro;

}

To read (do the reverse):

public byte[] getBlobFromDatabase(BigDecimal numFicheiro) throws BusinessException {

Connection conn = null;
try {

conn = (Connection) UtilsDB.getDataSource().getConnection();

CallableStatement ocs = null;
byte[] content = null;

try {

ocs = conn.prepareCall(DBResources.F_OBTEM_BLOB_BD);

ocs.registerOutParameter(1, OracleTypes.BLOB);
ocs.setBigDecimal(2, numFicheiro );

ocs.executeQuery();

BLOB blob = null;
if (ocs.getObject(1) instanceof BLOB) {
blob = (BLOB) ocs.getObject(1);
}

content = new byte[ (int) blob.length()];
InputStream blobstream = blob.getBinaryStream();
try {
blobstream.read(content , 0 , (int) blob.length());
} catch (IOException ioex) {
ioex.printStackTrace();
} finally {
try {
blobstream.close();
} catch (Exception ignored) {}
}
return content;

} catch (SQLException sqlex) {
sqlex.printStackTrace();
throw sqlex;
} finally {
UtilsDB.close(ocs);
}
} catch (Exception daoe) {
throw new BusinessException(daoe.getMessage() , daoe);
} finally {
UtilsDB.close(conn);
}

}

Also read from:

http://stackoverflow.com/questions/862355/overcomplicated-oracle-jdbc-blob-handling

public byte[] getBlobFromDatabase(BigDecimal numFicheiro) throws BusinessException {Connection conn = null;
try {conn = (Connection) UtilsDB.getDataSource().getConnection();

CallableStatement ocs = null;
byte[] content = null;

try {
Logger.getLogger(“pt.mapfre.pdf.dao”).
log(Level.INFO, “{? = call jf_k_merge.f_obtem_blob_BD(“+numFicheiro+”)}”);

ocs = conn.prepareCall(DBResources.F_OBTEM_BLOB_BD);

ocs.registerOutParameter(1, OracleTypes.BLOB);
ocs.setBigDecimal(2, numFicheiro );

ocs.executeQuery();

//                System.out.println(“CLO: ” + ocs.getObject(1));
//                System.out.println(“CLOB CLASS: ” + ocs.getObject(1).getClass());
//                System.out.println(“IMPORTED CLOB CLASS: ” + BLOB.class);

BLOB blob = null;
if (ocs.getObject(1) instanceof BLOB) {
blob = (BLOB) ocs.getObject(1);
}

content = new byte[ (int) blob.length()];
InputStream blobstream = blob.getBinaryStream();
try {
blobstream.read(content , 0 , (int) blob.length());
} catch (IOException ioex) {
ioex.printStackTrace();
} finally {
try {
blobstream.close();
} catch (Exception ignored) {}
}

return content;

} catch (SQLException sqlex) {
sqlex.printStackTrace();
throw sqlex;
} finally {
UtilsDB.close(ocs);
}

} catch (Exception daoe) {
Logger.getLogger(“pt.mapfre.pdf.dao”).
log(Level.SEVERE, “Erro na geracao de PDF”, daoe);
throw new BusinessException(daoe.getMessage() , daoe);
} finally {
UtilsDB.close(conn);
}
public byte[] getBlobFromDatabase(BigDecimal numFicheiro) throws BusinessException {

Connection conn = null;
try {

conn = (Connection) UtilsDB.getDataSource().getConnection();

CallableStatement ocs = null;
byte[] content = null;

try {
Logger.getLogger(“pt.mapfre.pdf.dao”).
log(Level.INFO, “{? = call jf_k_merge.f_obtem_blob_BD(“+numFicheiro+”)}”);

ocs = conn.prepareCall(DBResources.F_OBTEM_BLOB_BD);

ocs.registerOutParameter(1, OracleTypes.BLOB);
ocs.setBigDecimal(2, numFicheiro );

ocs.executeQuery();

//                System.out.println(“CLO: ” + ocs.getObject(1));
//                System.out.println(“CLOB CLASS: ” + ocs.getObject(1).getClass());
//                System.out.println(“IMPORTED CLOB CLASS: ” + BLOB.class);

BLOB blob = null;
if (ocs.getObject(1) instanceof BLOB) {
blob = (BLOB) ocs.getObject(1);
}

content = new byte[ (int) blob.length()];
InputStream blobstream = blob.getBinaryStream();
try {
blobstream.read(content , 0 , (int) blob.length());
} catch (IOException ioex) {
ioex.printStackTrace();
} finally {
try {
blobstream.close();
} catch (Exception ignored) {}
}

return content;

} catch (SQLException sqlex) {
sqlex.printStackTrace();
throw sqlex;
} finally {
UtilsDB.close(ocs);
}

} catch (Exception daoe) {
Logger.getLogger(“pt.mapfre.pdf.dao”).
log(Level.SEVERE, “Erro na geracao de PDF”, daoe);
throw new BusinessException(daoe.getMessage() , daoe);
} finally {
UtilsDB.close(conn);
}

}
}

http://download-west.oracle.com/docs/cd/B10501_01/java.920/a96654/oralob.htm#1043220

Deixe um Comentário

Spring JdbcTemplate calling Oracle store procedures or functions

After long long google search (My God! Why do we have to google for something that should be self-intuitive), I finally got my java program working  and calling a store procedure from Oracle.

The code before was this:

  /**
   *
   * @param connection
   * @param xml
   * @return
   * @throws SQLException
   */
  public String executaProcedimento (Connection connection,
                    String login,
                    String codPgm,
                    String xmlParams,
                    String urlWebAppServico)
  throws SQLException{

    CallableStatement
    stmt = connection.prepareCall(databaseObjects.STMT_F_EXEC_PROCEDIMENTO);
    //
    stmt.registerOutParameter(1, OracleTypes.VARCHAR);
    //
    stmt.setString(2, login);
    stmt.setString(3, codPgm);
    stmt.setString(4, xmlParams);
    stmt.setString(5, urlWebAppServico);
    stmt.execute();
    //System.out.println("xml:"+xml);
    String result = (String)stmt.getObject(1);

    stmt.close();
    return  result;

  }
  

And now a proud Spring equivallent one:

  /**
   *
   * @author Acacio Bernardo
   *
   */
  private class ProcedimentoTron
  extends StoredProcedure {

        private static final String SQL =
          "oracle_package_name.f_stored_function";

        public ProcedimentoTron(DataSource ds) {
            setDataSource(ds);
            setFunction(true);
            setSql(SQL);

            declareParameter(new SqlOutParameter("result", Types.VARCHAR));

            declareParameter(new SqlParameter   ("p_login", Types.VARCHAR));
            declareParameter(new SqlParameter   ("p_cod_pgm", Types.VARCHAR));
            declareParameter(new SqlParameter   ("p_xml_params", Types.VARCHAR));
            declareParameter(new SqlParameter   ("p_url_servico", Types.VARCHAR));

            compile();
        }

        public Map executa( String login,
                  String codPgm,
                  String xmlParams,
                  String urlWebAppServico) {
          //
          Map inputs = new HashMap();
            inputs.put("p_login", login);
            inputs.put("p_cod_pgm", codPgm);
            inputs.put("p_xml_params", xmlParams);
            inputs.put("p_url_servico", urlWebAppServico);
            return execute(inputs);
        }
    }

  /**
   *
   * @param connection
   * @param xml
   * @return
   * @throws SQLException
   */
  public String executaProcedimento (DataSource ds,
                    String login,
                    String codPgm,
                    String xmlParams,
                    String urlWebAppServico)
  throws SQLException{

    ProcedimentoTron proc =
         new ProcedimentoTron(ds);

    Map results = proc.executa(login, codPgm, xmlParams, urlWebAppServico);

    return  (String) results.get("result").toString();

  } 

The Oracle page where I found the information has an example, but it wasn't working because the order of the parameters was Wrong.
Is seems that first you must define the out parameter, and then the input parameters.

Deixe um Comentário

Trabalhar em J2EE

Andamos anos a estudar.

Lembro-me desde as aulas de educação visual até às de programação, estruturas de dados, redes.. para, no final, quando queremos comunicar nas reuniões, de forma eficaz, usamos técnicas tão sofisticadas como esta:

simuladores

simuladores

Deixe um Comentário