passagem de objetos entre java e oracle

53
Passagem de Objetos entre Java e Oracle Transformando e enviando Pojos Java como parâmetros para Procedures em PL/SQL no Oracle.

Upload: andre-reis

Post on 15-Jan-2015

1.507 views

Category:

Technology


0 download

DESCRIPTION

Transformando e enviando Pojos Java como parametros para Procedures em PL/SQL no Oracle

TRANSCRIPT

Page 1: Passagem de Objetos entre Java e Oracle

Passagem de Objetos entre Java e Oracle

Transformando e enviando Pojos Java como parâmetros para Procedures em PL/SQL no Oracle.

Page 2: Passagem de Objetos entre Java e Oracle

?

Page 3: Passagem de Objetos entre Java e Oracle

PL/SQL !!! / Java? Hibernate WTF??

Contrato com a Oracle de longo prazo

Máquina BD mais potente e ociosa

Algumas definições de segurança

Desempenho (“idas” ao banco)

Fatores:

Page 4: Passagem de Objetos entre Java e Oracle

Como “era” feito:

String sql = "insert into contatos (nome,email) values (?,?)";PreparedStatement stmt = con.prepareStatement(sql);stmt.setString(1, contato.getNome());stmt.setString(2, contato.getEmail());stmt.execute();

Page 5: Passagem de Objetos entre Java e Oracle

Como “era” feito:Statment stmt = con.createStatement(); ResultSet rs;rs = stmt.executeQuery("select * from contatos");List<Contato> contatos = new ArrayList<Contato>(); while (rs.next()) { int id = rs.getString("id"); String nome = rs.getString("nome"); String email = rs.getString("email"); Contato c = new Contato(id, nome, email); contatos.add(c); }

Page 6: Passagem de Objetos entre Java e Oracle

Depois:

session.save(contato);

Page 7: Passagem de Objetos entre Java e Oracle

Como “era” feito:String proc = "{call procInsereContato(?,?,?)}";CallableStatement cs = con.prepareCall(proc);cs.registerOutParameter(1, java.sql.Types.NUMERIC);cs.setString(2, contato.getNome());cs.setString(3, contato.getEmail());cs.execute();contato.setId(cs.getInt(1));

Page 8: Passagem de Objetos entre Java e Oracle

Como “era” feito:CREATE OR REPLACE PROCEDURE procInsereContato(

contatoId OUT Contatos.id%TYPE, contatoNome IN Contatos.nome%TYPE, contatoEmail IN Contatos.email%TYPE)

ISBEGIN INSERT INTO Contatos (id, nome, email) VALUES (SQ_CON.NEXTVAL, contatoNome, contatoEmail) RETURNING id INTO contatoId; END;

Page 9: Passagem de Objetos entre Java e Oracle

Como “era” feito:public class PessoaBean {

private long idPessoa;private Date dtNascimento;private String nome;private char sexo;private int idNacionalidade;private int idUF;private int idNaturalidade;private String naturalidadeExt;private int idCor;private int idEstadoCivil;private String telResidencial;private String telCelular;private String telComercial;private String email;private boolean stAtivo;private FiliacaoBean filiacaoBean;private DadoCivilBean dadoCivilBean;private EnderecoBean enderecoBean;

Page 10: Passagem de Objetos entre Java e Oracle

Como “era” feito:String proc = "{call procCadastraPessoa(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}";CallableStatement cs = con.prepareCall(proc);cs.setLong(1, pessoa.getIdPessoa());cs.setDate(2, pessoa.getDtNascimento());cs.setString(3, Character.toString(pessoa.getSexo()));cs.setInt(4, pessoa.getIdNacionalidade());cs.setInt(5, pessoa.getIdUF());cs.setInt(6, pessoa.getIdNaturalidade());cs.setString(7, pessoa.getNaturalidadeExt());cs.setInt(8, pessoa.getIdCor());cs.setInt(9, pessoa.getIdEstadoCivil());cs.setString(10, pessoa.getTelResidencial());cs.setString(11, pessoa.getTelCelular());

Page 11: Passagem de Objetos entre Java e Oracle
Page 12: Passagem de Objetos entre Java e Oracle

String proc = "{call procCadastraPessoa(?)}"; CallableStatement cs = con.prepareCall(proc); cs.setObject(1, pessoa); Pessoa p = cs.getObject(2);

PROCEDURE procCadastraPessoa(Pessoa IN p);

Page 13: Passagem de Objetos entre Java e Oracle
Page 14: Passagem de Objetos entre Java e Oracle
Page 15: Passagem de Objetos entre Java e Oracle

Bizzaro!?

Page 16: Passagem de Objetos entre Java e Oracle

ojdbc14.jarojdbc14.jar

Page 17: Passagem de Objetos entre Java e Oracle

Primeira versãopublic class Bairro {

private int id;private String nome;public final String getNome() {

return nome;}public final void setNome(String nome) {

this.nome = nome;}public final int getId() {

return id;}public final void setId(int id) {

this.id = id;}

}

Page 18: Passagem de Objetos entre Java e Oracle

Primeira versãopublic class Bairro {

private int id;private String nome;// getters e setters suprimidospublic STRUCT toSTRUCT(OracleConnection oconn)

throws SQLException {...

}public void toBEAN(STRUCT struct) throws

SQLException {...

}}

Page 19: Passagem de Objetos entre Java e Oracle

Primeira versão

public STRUCT toSTRUCT(OracleConnection oconn) throws SQLException {

StructDescriptor sd = StructDescriptor.createDescriptor("TP_BAIRRO", oconn);

Object[] attributes = { ( 0 >= this.id ? null : this.id ),( "".equals(this.nome) ? null : this.nome )

};return new STRUCT(sd, oconn, attributes);

}

Page 20: Passagem de Objetos entre Java e Oracle

Primeira versãopublic void toBEAN(STRUCT struct) throws SQLException { if (null != struct) { Object[] attributes = struct.getOracleAttributes();

if (null != attributes[0]) { this.setId(((NUMBER)attributes[0]).intValue()); } if (null != attributes[1]) { this.setNome(((CHAR)attributes[1]).getString()); } } }

Page 21: Passagem de Objetos entre Java e Oracle

String proc = "{call procCadastraBairro(?)}";OracleCallableStatement cs = oconn.prepareCall(proc);cs.setSTRUCT(1, bairro.toSTRUCT(oconn));cs.registerOutParameter(1, OracleTypes.STRUCT, "TP_BAIRRO");cs.execute();bairro.toBEAN(cs.getSTRUCT(1));

Primeira versãoDAO

Page 22: Passagem de Objetos entre Java e Oracle

Primeira versão

CREATE OR REPLACE TYPE TP_BAIRRO AS OBJECT ( id NUMBER(3), nome VARCHAR2(50));

GRANT EXECUTE ON TP_BAIRRO TO USUARIO;

ORACLE

Page 23: Passagem de Objetos entre Java e Oracle

CREATE OR REPLACE PROCEDURE procCadastraBairro( bairro IN OUT TP_BAIRRO)

ISBEGIN INSERT INTO Bairros (id, nome) VALUES (SQ_BAI.NEXTVAL, bairro.nome) RETURNING id INTO bairro.id; END;

Primeira versãoORACLE

Page 24: Passagem de Objetos entre Java e Oracle

CREATE OR REPLACE PROCEDURE procCadastraBairro( bairro IN OUT TP_BAIRRO)

IS bairroId Bairros.id%TYPE;BEGIN

INSERT INTO Bairros (id, nome) VALUES (SQ_BAI.NEXTVAL, bairro.nome) RETURNING id INTO bairroId; SELECT TP_BAIRRO(id, nome) INTO bairro FROM Bairros WHERE id = bairroId;

END;

Primeira versãoORACLE

Page 25: Passagem de Objetos entre Java e Oracle

Primeira versãoLISTA no DAO

String proc = "{call procPesquisarBairro(?,?)}";OracleCallableStatement cs = oconn.prepareCall(proc);cs.setSTRUCT(1, bairro.toSTRUCT(oconn));cs.registerOutParameter(2, OracleTypes.ARRAY, "TPLISTA_BAIRRO");cs.execute();

CONTINUA...

Page 26: Passagem de Objetos entre Java e Oracle

Primeira versãoLISTA no DAO

ARRAY array = cs.getARRAY(2);Datum[] lista = array.getOracleArray();List<Bairro> bairros = new ArrayList<Bairro>();for (int i = 0; i < lista.length; i++) {

Bairro bairro = new Bairro();bairro.toBEAN((STRUCT)lista[i]);bairros.add(bairro);

}return bairros;

Page 27: Passagem de Objetos entre Java e Oracle

Primeira versão

CREATE OR REPLACE TYPE TPLISTA_BAIRRO AS TABLE OF TP_BAIRRO;

GRANT EXECUTE ON TPLISTA_BAIRRO TO USUARIO;

ORACLE

Page 28: Passagem de Objetos entre Java e Oracle

Primeira versão

CREATE OR REPLACE TYPE TPLISTA_BAIRRO AS TABLE OF NUMBER;CREATE OR REPLACE TYPE TP_BAIRRO AS OBJECT ();/** Objetos desfeitos / inicio reconstrucao **/CREATE OR REPLACE TYPE TP_BAIRRO AS OBJECT ( id NUMBER(3), nome VARCHAR2(50));CREATE OR REPLACE TYPE TPLISTA_BAIRRO AS TABLE OF TP_BAIRRO;

ORACLE

Page 29: Passagem de Objetos entre Java e Oracle

CREATE OR REPLACE PROCEDURE procPesquisarBairro( bairro IN TP_BAIRRO, listaBairros OUT TPLISTA_BAIRRO)

ISBEGIN

SELECT TP_BAIRRO(id, nome) BULK COLLECT INTO listaBairros FROM Bairros WHERE nome = bairro.nome;

END;

Primeira versãoORACLE

Page 30: Passagem de Objetos entre Java e Oracle

SELECT VALUE(e) BULK COLLECT INTO listaBairros FROM TABLE( CAST( MULTISET(

SELECT id, nome

FROM Bairros WHERE nome = bairro.nome

) AS TPLISTA_BAIRRO)) e;

Primeira versãoORACLE

Page 31: Passagem de Objetos entre Java e Oracle

Primeira versão

Object[] attributes = { int/long, // NUMBERString, // VARCHAR2boolean ? 1 : 0, // NUMBER(1)3 estados ? 1 : 0 : null, // NUMBER(1)util.Date ? new Timestamp(date.getTime()), // DATEOutroTipo.toSTRUCT(oconn), // TP_OUTROTIPOString ? CLOB.getEmptyCLOB(), // CLOBlistaOutroTipoArray // TPLISTA_OUTROTIPO

};

toSTRUCT()

Page 32: Passagem de Objetos entre Java e Oracle

Primeira versãotoSTRUCT()

ARRAY listaOutroTipoArray = null;ArrayDescriptor ad = ArrayDescriptor.createDescriptor("TPLISTA_OUTROTIPO", oconn);List<Object> listaItems = new ArrayList<Object>();

for (OutroTipo outro : this.listaOutroTipo) {listaItems.add(outro.toSTRUCT(oconn));

}listaOutroTipoArray =

new ARRAY(ad, oconn, listaItems.toArray());}

Page 33: Passagem de Objetos entre Java e Oracle

Primeira versãotoBEAN()

Object[] valores = struct.getOracleAttributes();((NUMBER)valores[0]).intValue();((NUMBER)valores[1]).longValue();((CHAR)valores[2]).getString();((NUMBER)valores[3]).booleanValue();((DATE)valores[4]).timestampValue();this.outroTipo = new OutroTipo();this.outroTipo.toBEAN((STRUCT)valores[5]);

Page 34: Passagem de Objetos entre Java e Oracle

Primeira versãotoBEAN()

CLOB cl = ((CLOB)valores[6]); Reader reader = cl.characterStreamValue(); StringBuffer sb = new StringBuffer();int nchars = 0;char[] buffer = new char[10]; while((nchars = reader.read(buffer)) != -1) {

sb.append(buffer, 0, nchars);} reader.close();this.setDescricao(sb.toString());

Page 35: Passagem de Objetos entre Java e Oracle

Primeira versãotoBEAN()

this.listaOutroTipo = new ArrayList<OutroTipo>();Datum[] lista = ((ARRAY)valores[7]).getOracleArray();for (int i = 0; i < lista.length; i++) {

OutroTipo outro = new OutroTipo();outro.toBEAN((STRUCT)lista[i]);this.listaOutroTipo.add(outro);

}

Page 36: Passagem de Objetos entre Java e Oracle

Primeira versãoimport java.io.IOException;import java.io.Reader;import java.sql.SQLException;import java.util.ArrayList;import java.util.Date;import java.util.List;import oracle.jdbc.OracleConnection;import oracle.sql.ARRAY;import oracle.sql.ArrayDescriptor;import oracle.sql.CHAR;import oracle.sql.CLOB;import oracle.sql.DATE;import oracle.sql.Datum;import oracle.sql.NUMBER;import oracle.sql.STRUCT;import oracle.sql.StructDescriptor;

Page 37: Passagem de Objetos entre Java e Oracle

Bizzaro!?

Page 38: Passagem de Objetos entre Java e Oracle
Page 39: Passagem de Objetos entre Java e Oracle
Page 40: Passagem de Objetos entre Java e Oracle

OracleTypeConverter

@ DBType(value)

@ NotInType

@ SendNull

OracleTypeConverter

STRUCTPrinter

Page 41: Passagem de Objetos entre Java e Oracle

@DBType("TP_BAIRRO")public class Bairro {

private int id;private String nome;// getters e setters suprimidos

}

OracleTypeConverter

Page 42: Passagem de Objetos entre Java e Oracle

String proc = "{call procCadastraBairro(?)}";OracleCallableStatement cs = oconn.prepareCall(proc);cs.setSTRUCT(1, OracleTypeConverter.toSTRUCT(oconn, bairro));cs.registerOutParameter(1, OracleTypes.STRUCT, OracleTypeConverter.getDBTypeAnnotation(Bairro.class));cs.execute();bairro = OracleTypeConverter.toBEAN(Bairro.class, cs.getSTRUCT(1));

DAO

OracleTypeConverter

Page 43: Passagem de Objetos entre Java e Oracle

cs.setARRAY(1, OracleTypeConverter.toARRAY(oconn, listaBairros, "TPLISTA_BAIRRO"));cs.registerOutParameter(2, OracleTypes.ARRAY, "TPLISTA_BAIRRO");cs.execute();listaBairros = OracleTypeConverter.toList(Bairro.class,cs.getARRAY(2));

LISTA no DAO

OracleTypeConverter

Page 44: Passagem de Objetos entre Java e Oracle

@DBType("TP_PAGINACAO")public class Paginacao {

private int pagina = 1;private int quantRegistros = 10;@SendNullprivate int total;@NotInTypeprivate String action;@DBType("TRISTATES")private String ativo;// getters e setters suprimidos

}

OracleTypeConverter

Page 45: Passagem de Objetos entre Java e Oracle

CREATE OR REPLACE TYPE TP_PAGINACAO AS OBJECT ( pagina NUMBER, quantRegistros NUMBER, total NUMBER, ativo NUMBER(1));

ORACLE

OracleTypeConverter

Page 46: Passagem de Objetos entre Java e Oracle

OracleTypeConverter@DBType("TP_OCORRENCIA")public class Ocorrencia {

private Long id;private Assunto assunto; private Date dataCadastro;private boolean stImprimirCarta;@DBType("CLOB")private String descricao;@DBType("TPLISTA_ENCAMINHAMENTO")private List<Encaminhamento> listaEncaminhamento;@SendNull@DBType("TPLISTA_LOTEIMPRESSAO")private List<LoteImpressao> listaLoteImpressao;

Page 47: Passagem de Objetos entre Java e Oracle

CREATE OR REPLACE TYPE TP_OCORRENCIA AS OBJECT ( id NUMBER, assunto TP_ASSUNTO, dataCadastro DATE, stImprimirCarta NUMBER(1), descricao CLOB, listaEncaminhamento TPLISTA_ENCAMINHAMENTO, listaLoteImpressao TPLISTA_LOTEIMPRESSAO );

ORACLE

OracleTypeConverter

Page 48: Passagem de Objetos entre Java e Oracle

cs.setSTRUCT(1, OracleTypeConverter.toSTRUCT(oconn, ocorrencia));cs.registerOutParameter(2, OracleTypes.CLOB);cs.execute();CLOB clob = cs.getCLOB(2);Writer sw = clob.setCharacterStream(1L); sw.write(ob.getDescricao().trim().toCharArray());sw.flush();sw.close();

DAO – Enviar CLOB

OracleTypeConverter

Page 49: Passagem de Objetos entre Java e Oracle

OracleTypeConverter

Page 50: Passagem de Objetos entre Java e Oracle

OracleTypeConverterNão converte FLOAT, DOUBLE, BigDecimal, BigInteger(ainda não precisei destes);

A converão é baseada na ordem dos atributos;

Cuidado com o tamanho da String para VARCHAR(?) e do Integer para NUMBER(?);

Até o java 1.6 não existe suporte para o tipo Boolean do PL/SQL;

Necessita de refatoração urgente!!!

Page 51: Passagem de Objetos entre Java e Oracle

ReferênciasOracle Database JDBC Developer's Guide and Reference:

Working with Oracle Object Typeshttp://download.oracle.com/docs/cd/B19306_01/java.102/b14355/oraoot.htm

Using PL/SQL Collections and Recordshttp://download.oracle.com/docs/cd/B19306_01/appdev.102/b14261/collections.htm

Oracle Database JPublisher User's Guide:

Introduction to JPublisherhttp://download.oracle.com/docs/cd/B19306_01/java.102/b14188/intro.htm

Introduction to JPublisher # JDBC Mappinghttp://download.oracle.com/docs/cd/B19306_01/java.102/b14188/intro.htm#sthref50

Page 52: Passagem de Objetos entre Java e Oracle
Page 53: Passagem de Objetos entre Java e Oracle

Obrigado!

André Luis F. Reis

[email protected]

twitter.com/andrelfreis

facebook.com/andrelfreis

linkedin.com/in/andrelfreis