Persistência de Dados Com a Tecnologia ORM Hibernate
-
Upload
paulo-daniel -
Category
Documents
-
view
217 -
download
0
description
Transcript of Persistência de Dados Com a Tecnologia ORM Hibernate
-
Gostei(2) (0)
Buscar
comentrios postfavorito(6)
Persistncia de dados com atecnologia ORM HibernateNeste artigo trabalharemos a persistncia, que um dosconceitos fundamentais em desenvolvimento deaplicativos. O Hibernate uma das solues ORM maiscompletas e utilizadas do mercado e ser o principalconceito deste artigo.
OMapeamentoObjetoRelacional(ORM)consisteemumaformaautomatizadae
transparentedepersistirobjetospertencentesaumaaplicaoemsuasrespectivas
tabelasemumbancodedadosrelacional,usandoparaisso,tecnologiascomoo
0 0Curtir0
LOGIN
-
Hibernate,responsveispordescreveromapeamentoentreosobjetoseobancode
dados(BAUEReKINK,2005).
ConformeLuckoweMelo(2010),umasoluoORMconsistebasicamentenos
seguintespontos:
UmaAPIpararealizarasoperaesCRUDbsicasemobjetosdeclasses
persistentes
UmalinguagemouAPIparaespecificaodeconsultasreferentessclasses
oussuaspropriedades
Umrecursoparaespecificaromapeamentodemetadados
UmatcnicaparaqueaimplementaoORMinterajacomobjetos
transacionaispermitindoexecutarverificaesdotipoleiturasuja
(dirtycheking),buscasporassociaesociosas(lazyassociationfetching)e
outrastcnicasdeotimizao.
HibernateOHibernateasoluoORMJavaqueconsisteemumaferramentapararealizaro
mapeamentoobjetorelacionaldeformacompleta.Atecnologiaseguea
especificaoJPA(JavaPersistenceAPI),quetratadeentidades,mapeamentos,
interfacesparagerenciarapersistnciaelinguagemdeconsulta(LUCKOWeMELO,
2010).
OHibernatefuncionacomoumintermedirioentreainteraodoaplicativocomo
bancodedadosrelacional,assimodesenvolvedorpoderseconcentrarno
problemadonegcioasertrabalhado.Asoluotambmnoexigeaobedincias
regrasespecficasdoHibernateeseintegrafacilmenteaosaplicativosnovose
existentes,norequerendomudanasbruscasnorestantedaaplicao.(BAUERe
KING,2005).
AarquiteturadoHibernatebaseadaeminterfacesdeprogramao.Conforme
BauereKink(2005),taisinterfacespodemserclassificadascomo:
InterfaceschamadasporaplicativosparaexecutaroperaesCRUDbsicase
deconsulta.Essasinterfacessoopontoprincipaldalgicadenegciosde
aplicativosdoHibernate,soelas:Session,TransactioneQuery
-
Interfaceschamadaspelocdigodeinfraestruturadoaplicativoparaconfigurar
oHibernate,queincluemprincipalmenteainterfaceConfiguration
Interfacescallback,quepermitemareaodoaplicativoaoseventosque
vieremaocorrerdentrodoHibernate
Interfacesquepermitemestenderasfuncionalidadesdemapeamentodo
Hibernate,comoUserType,CompositeUserTypeeIdentifierGenerator.
AFigura1apresentaoesquemadealtonveldaarquiteturadoHibernate.O
diagramamostraarelaodomesmocomaaplicaoeobancodedados,bem
comosuaconfiguraoepropriedadesnecessriasparaapersistnciadosdados.
-
Figura1.VisogeraldealtonveldaarquiteturadoHibernate.
AtecnologiaHibernatesuportamuitasabordagenseaFigura2apresentasua
arquiteturacompreensiva,ondeosdetalhesdaaplicaosoabstradose
especificadospeloHibernate.
-
Figura2.VisogeraldealtonveldaarquiteturacompreensivadoHibernate.
Essediagramaestdividobasicamenteemtrscamadas:
Aplicao,ondeestpresentealgicadenegcio
Camadadepersistncia,ondeseencontramaspropriedadesdoHibernate
e
Bancodedados,ondefinalmenteosdadossopersistidos.
importantequeseconheaoconceitodasinterfacespresentesnacamadade
persistnciadodiagrama:
Session:PrincipalinterfaceusadapelosaplicativosdoHibernate.ondeo
HibernateiniciadoparaarealizaodeoperaesCRUD,execuode
consultas,controledetransaesetc.Essainterfaceresponsvelpelo
gerenciamentodeestadosdosobjetos
SessionFactory:ForneceaoaplicativoinstnciasdainterfaceSession.Realiza
aindaoarmazenamentodeinstruesSQLemetadadosdemapeamento
-
utilizadospeloHibernateemtempodeexecuo
Transaction:Realizaatarefadeabstrairocdigodoaplicativodousurioque
implementariaatransaosubjacente.Talabstraopermiteocontroledos
limitesdetransaespeloaplicativo,mantendoaportabilidadedosaplicativos
doHibernatemesmoentreambientesdeexecuodistintos.Ainterface
Transactionopcional
TransactionFactory:ForneceinstnciasdainterfaceTransaction.Ainterface
opcional
ConnectionProvider:ConsistenumafbricadeconexesJDBC,abstraindo
DriverManageradjacentesdaaplicao.Tambmopcional.
Opes de consulta com HibernateExistemaindaasinterfacesQueryeCriteriapertencentesinterfaceSession.A
interfaceQueryconsistenamaneiramaisdiretadeexecuodeconsultaspara
obtenodasinformaesdesejadasemumbancodedados,asconsultasso
escritasemHQL(linguagemdeconsultadoHibernatemuitoparecidacomSQL),que
porsuavez,tambmpodeserutilizadaparaarealizaodasconsultas.Porm,ao
invsdeseremrealizadassobretabelasdobancodedados,asconsultasso
baseadasemobjetos,umainstnciadaclasseQuerydeveserespecificadapara
fazeraligaodosparmetrosdeconsultaselimitarosresultadosdevolvidospelas
mesmas.
Observeumexemploaseguir,ondeumainstnciadaclasseQueryrecebeoutra
instnciadainterfaceSessionquerealizaacriaodeumaconsulta:
Queryconsulta=sessao.createQuery(selectffromFuncionariowheref.categoria=Administrativo)
Essaconsultafazabuscadefuncionriosquepertenamadministrao.Diferente
dautilizaonativadeconsultasSQLquesoaplicadasdiretamentestabelasdo
bancodedados,aoperaodeconsultareferenciaoobjetoFuncionario.
AinterfacecriteriasimilarQuery,permitindoacriaoeexecuodeconsultas
baseadasemcritriosorientadosaobjetos.umadasmelhoresabordagensquando
-
umaconsultapassaasermuitocomplexa.Consistebasicamentenaformulaode
consultastendoemvistaoscritriosdousurio.Ocdigoaseguircontmuma
consultaenvolvendoapenasumaclasse,ondeumainstnciadaAPIdefinidapara
receberumainstnciadainterfaceSessionquepermiteacriaodeumaconsulta:
Criteriacriteria=sessao.createCriteria(Funcionario.class);Listfuncionarios=criteria.list();
Umavariveldotipolistespecificadaerecebeumalistadefuncionriosno
momentodainvocaodomtodolistdainterfacecriteria.
Estudo de caso: Cadastro de funcionriosOestudodecasoparademonstrarautilizaodoHibernatecomosoluoparaa
persistnciadedadosadmiteumcadastrosimplesdefuncionrios.
OSGBDutilizadopararealizarapersistnciaseroPostgreSQL,quepodeser
baixadodeseusiteprincipal(seoLinks).
Paraacriaodobancodedados,digiteocomandoSQLaseguirnoSQLShelldo
PostgreSQLouemumarquivoSQLdoSGBD:
CREATEDATABASEFUNCIONARIO_DB;
Emseguida,devesercriadaatabelafuncionrio,conformeasintaxedecriaoda
tabelapresentenaListagem1.
Listagem1.ComandoSQLparaacriaodatabelafuncionario.
CREATETABLEFUNCIONARIO(ID_FUNCIONARIOSERIALPRIMARYKEY,NOMEVARCHAR(80)NOTNULL,CPFVARCHAR(14)NOTNULL,CATEGORIAVARCHAR(20)NOTNULL,SALARIONUMERIC(8,2)NOTNULL);
-
Instalao do HibernateParainiciarostrabalhoscomoHibernate,necessrioquesefaaodownloaddo
mesmonoseusiteoficial(videseoLinks).Baixeoarquivo.zipcorrespondente
ltimaversodatecnologia.Abibliotecacomplementarslf4jtambmdeveser
adquirida(seoLinks).Faaodownloaddoarquivo.zipdasduasverses
disponveis.Demodoapermitiracomunicaodaaplicaocomobancodedados
paraarealizaodasoperaesnecessrias,precisofazerusododriverJDBC
JavaDatabaseConnectivity,queespecificacomoessacomunicaoserfeita.Para
esteestudo,utilizaremosoSGBDPostgreSQL,cujodownloaddodriverpodeser
feito(seoLinks).Apsotrminodosdownloads,extraiaosarquivos.
AbraoEclipse,casoaindanotenhafeitoodownloaddoIDE,useolinkdisponvel
naseoLinks.ExistemvriasopesdoIDEparadownload,masparaeste
exemploutilizaremosaopoEclipseIDEforJavaEEDevelopers.Depoisdeaberta
crieumnovoprojetoJavachamadoHibernatePersistence.Crietambmapastalib
doprojeto,quedeverreceberosarquivos.jarqueforambaixadosanteriormente.
CopieosmesmosparaapastainternamenteeadicioneasaoBuildPathdoprojeto.
NaFigura3observecomoficaroprojetoHibernatePersistenceapsserem
adicionadastodasasbibliotecaseapsacriaodetodosospacoteseclasses.
-
Figura3.ProjetoHibernatePersistencefinalizado.
Configurao do HibernateOarquivodeconfiguraodoHibernatehibernate.cfg.xmldeveestarnopacote
raizdoprojeto.Omesmocontminformaescomoaspropriedadesdaconexo
JDBCparaoHibernate,aconfiguraoparaopooldoprojetoeopesdedebug(as
configuraesdedebugsoopcionais).AListagem2contmoarquivode
configuraodoHibernateparaoprojetoHibernatePersistence.
Listagem2.ArquivodeconfiguraodoHibernate.
org.hibernate.dialect.PostgreSQLDialectorg.postgresql.Driverjdbc:postgresql://localhost:5432/funcionario_dbpostgresadministrator520300503000truetruetruetrue
Aprimeirapropriedadedefinidanoarquivotemcomonomedialect,quesempre
receberumaclasseDialectcomovalor,demodoapermitiracomunicaodo
-
Hibernatecomobancodedadosemquesto.AlmdodriverJDBC,todobancode
dadosprecisateraclasseDialectparaconversarcomoHibernate.Asprximas
propriedadesdoarquivopertencemconexocomobancodedados,incluindo
informaescomoaclassedodriverJDBC,aURLdeconexo,ousurioeasenha
deconexocombancodedados.C3POopooldeconexoutilizadopara
especificarasconfiguraesdepooldoHibernate,eomesmocontmasseguintes
propriedades:
c3po.min.size:Defineonmeromnimodeconexesquesomantidassempre
preparadaspeloC3PO
c3po.max.size:Nmeromximodeconexesnopool
c3po.timeout:Tempolimitepararemoodeconexesinativasnopool
c3po.max.statements:Mximodedeclaraesqueiroparacache
c3po.idle_test_period:Tempodeinatividadedeumaconexoantesdeser
validada.
Finalmentesoespecificadososparmetrosdaspropriedadesdedebug.Noarquivo
asseguintespropriedadesdedepuraoforamdefinidas:
show_sql:HabilitaoaparecimentodetodasassadasparacomandosSQLno
console
format_sql:ImprimeocomandoSQLexecutadodeformalegvel
generate_statistics:Habilitaacoletadeestatsticasparaposteriorajustede
desempenho
use_sql_comments:PermitequeoHibernategerecomentriosjuntoaoSQL
prafacilitaradepurao.
Criao da classe HibernateUtil.javaNoprojetoHibernatePersistence,crieumnovopacotedenome
hibernatePersistence.util.EmseguidacrieaclasseHibernateUtil.java,quefara
ligaoentreoarquivodeconfiguraoeaconexocomobancodedados.A
Listagem3apresentaocdigofontedessaclasse.
Listagem3.ClasseHibernateUtil.java.
packagehibernatePersistence.util;
-
importorg.hibernate.*;publicclassHibernateUtil{privatestaticfinalSessionFactorysessionFactory=buildSessionFactory();privatestaticSessionFactorybuildSessionFactory(){try{Configurationcfg=newConfiguration();cfg.configure("hibernate.cfg.xml");returncfg.buildSessionFactory();}catch(Throwablee){System.out.println("Erro:"+e);thrownewExceptionInInitializerError(e);}}publicstaticSessionFactorygetSessionFactory(){returnsessionFactory;}}
OmtodoestticoprivadobuildSessionFactorydaclasseHibernateUtil.java
responsvelporcriarumaSessionFactorydoHibernatebaseadanoarquivo
hibernate.cfg.xml.UmapropriedadeSessionFactoryserretornadapelomtodo
getSessionFactoryquandoesteforchamado.
Criao da classe conexaoHibernatePostgreSQL.javaCrieumnovopacotechamadoHibernatePersistence.conexao,enelecrieaclasse
conexaoHibernatePostgreSQL.java,quetestaraconexocomobancodedados.
EladeverconterocdigofonteapresentadonaListagem4.
Listagem4.CdigofontedaclasseconexaoHibernatePostgreSQL.java.
packagehibernatePersistence.conexao;importorg.hibernate.Session;
-
publicclassConexaoHibernatePostgreSQL{publicstaticvoidmain(String[]args){Sessionsessao=null;try{sessao=HibernateUtil.getSessionFactory().openSession();System.out.println("Conectou!");}finally{sessao.close();}}}
Nessaclasse,omtodogetSessionFactorychamadoeretornaumaSessionFactory
baseadanoarquivodeconfiguraodoHibernate,possibilitandoaaberturadeuma
Session.Issopermitequeaconexocomobancodedadosemquestoseja
realizada.AsadaparaaexecuodaclassedeveseraexpressoConectou!.
Criao e mapeamento da classe Funcionario.javaAclasseFuncionario.javadevetercampossemelhantesaosatributosdatabela
funcionariodobancodedados,poisserumaclasseentidadedoHibernate.O
mapeamentodaclasseserfeitoutilizandoatcnicaannotationse,paraisso,
necessriocopiaroarquivohibernatejpa2.1api1.0.0.Final.jar,presentenapasta
doHibernatequefoidescompactada.CrieopacoteHibernatePersistence.funcionario
edentrodelecrieaclassefuncionario.java,queficarcomonaListagem5apsa
criaoemapeamento.
Listagem5.ClasseFuncionario.java.
packagehibernatePersistence.funcionario;importjava.io.Serializable;importjavax.persistence.*;@EntitypublicclassFuncionarioimplementsSerializable{privatestaticfinallongserialVersionUID=1L;
-
@Id@GeneratedValueprivateintid_funcionario;privateStringnome;privateStringcpf;privateStringcategoria;privatefloatsalario;//gerargetsesets}
Obrigatoriamenteaclassedeverconteraannotation@Entity,assimoHibernate
reconhecersuaspropriedadescomosendoreferentestabelacorrespondente
criadanobancodedados.Asannotations@Ide@GeneratedValuedefinemqueo
campoid_funcionariocorrespondechaveprimriadatabelaequeestaserauto
incrementada.
OarquivodeconfiguraodoHibernate,hibernate.cfg.xml,deverseralteradopara
reconheceraclasseFuncionario.java.Aseguirtemosalinhademapeamentoda
classeaseradicionadaaoarquivoantesdatag:
Criao da classe FuncionarioHibernateDAO.javaAclasseDAODataAccessObjectcontmosmtodosquefazemoacessoaos
dados.ComousodoHibernate,asoperaesCRUDsofeitassemanecessidade
deutilizaodecdigoSQL,assimaclasselimpaedefcilcompreenso.No
pacotehibernatePersistence.funcionariocrieaclasseFuncionarioHibernateDAO.java,
quedeverconterocdigofonteobservadonaListagem10.
Listagem10.ClasseFuncionarioHibernateDAO.java
packagehibernatePersistence.funcionario;importhibernatePersistence.util.HibernateUtil;importjava.util.ArrayList;
-
importorg.hibernate.*;
publicclassFuncionarioHibernateDAO{privateSessionsession;privateTransactiontransaction;publicvoidsalvar(Funcionariofuncionario){try{this.session=HibernateUtil.getSessionFactory().openSession();this.transaction=this.session.beginTransaction();this.session.save(funcionario);this.transaction.commit();}catch(HibernateExceptione){System.out.println("Nofoipossvelinserir.Erro:"+e.getMessage());}finally{try{if(this.session.isOpen()){this.session.close();}}catch(Throwablee){System.out.println("Erroaofecharaoperao.Mensagem:"+e.getMessage());}}}publicvoiddeletar(Funcionariofuncionario){try{this.session=HibernateUtil.getSessionFactory().openSession();this.transaction=this.session.beginTransaction();this.session.delete(funcionario);this.transaction.commit();}catch(HibernateExceptione){System.out.println("Nofoipossveldeletar.Erro:"+e.getMessage());}finally{try{if(this.session.isOpen()){this.session.close();}}catch(Throwablee){System.out.println("Erroaofecharaoperao.Mensagem:"+e.getMessage());}}}
-
publicvoidalterar(Funcionariofuncionario){try{this.session=HibernateUtil.getSessionFactory().openSession();this.transaction=this.session.beginTransaction();this.session.update(funcionario);this.transaction.commit();}catch(HibernateExceptione){System.out.println("Nofoipossvelalterar.Erro:"+e.getMessage());}finally{try{if(this.session.isOpen()){this.session.close();}}catch(Throwablee){System.out.println("Erroaofecharaoperao.Mensagem:"+e.getMessage());}}}publicArrayListlistar(){ArrayListfuncionarios=newArrayList();try{this.session=HibernateUtil.getSessionFactory().openSession();this.transaction=this.session.beginTransaction();Criteriafiltro=this.session.createCriteria(Funcionario.class);funcionarios=(ArrayList)filtro.list();this.transaction.commit();}catch(Throwablee){if(this.transaction.isActive()){this.transaction.rollback();}}finally{try{if(this.session.isOpen()){this.session.close();}}catch(Throwablee){System.out.println("Erroaofecharaoperao.Mensagem:"+e.getMessage());}}returnfuncionarios;}}
-
Aseguirobserveaanlisedaslinhasmaisimportantesdomtodo:
this.session=HibernateUtil.getSessionFactory().openSession()Nestalinha
umavariveldotipoSessionrecebeoresultadodachamadaaomtodo
getSessionFactory.EssemtodoretornaumasessionFactory,possibilitando
assimaaberturadasessoatravsdomtodoopenSession
this.transaction=this.session.beginTransaction()Avariveltransaction
recebesessionque,porsuavez,iniciaatransaoatravsdachamadaao
mtodobeginTransaction(essalinhaopcional)
this.session.save(funcionario)Achamadaaomtodosaverealizauma
operaodeinsertnobancodedados,assim,asinformaesdofuncionrio
passadascomoparmetrosoinseridasnomesmo
this.transaction.commit()Atransaorealizadaconfirmadaatravsda
chamadaaomtodocommit
Osmtodosdeletarealterarnosedistinguemmuitodomtodosalvar,dessa
forma,serfeitaaanliseapenasdaslinhasquenoserepetem.
Nomtododeletartemosalinhathis.session.delete(funcionario)ondeomesmo
executaumaoperaodedeletenobancodedados,excluindoosregistros
correspondentesaosdofuncionriopassadoporparmetro.
Jomtodoalterarexecutaaoperaodeupdatenobancodedadosatravsda
linhathis.session.update(funcionario).NestalinhaavariveldotipoSessionchama
omtodoupdatedoHibernatequerealizaumaoperaodeupdatenobancode
dados,alterandoasinformaesdeumfuncionriojexistentenomesmocomas
novasinformaespassadasporparmetro.
OmtodolistardotipoArrayListretornaumalistacomosfuncionriosexistentesno
banco.Nestemtodopodemosdestacarasseguinteslinhas:
Criteriafiltro=this.session.createCriteria(Funcionario.class)Umavarivel
dotipocriteriarecebeavarivelglobalsession,quefazumachamadaao
mtodocreateCriteria.Essemtodofazumaconsultaaobancoatravsda
classefuncionrio
funcionarios=(ArrayList)filtro.list()OArrayListdefuncionriosdeclarado
noinciodomtodorecebeavarivelfiltro,quecontmoresultadoda
consultarealizadanalinhaanterior.Omtodolistinvocadopelavarivel
-
retornaumalistadosobjetosconsultados.
Inserindo funcionriosNopacotehibernatePersistence.funcionariofoicriadaaclasse
OperacoesFuncionario.java,presentenaListagem11.Essaclasseapresentaum
exemplodeinserodefuncionriosnobancodedados.
Listagem11.ClasseOperacoesFuncionario.java
packagehibernatePersistence.funcionario;publicclassOperacoesFuncionario{publicstaticvoidmain(String[]args){FuncionarioHibernateDAOfuncionarioHibernateDAO=newFuncionarioHibernateDAO();String[]nomes={"LysMaria","MarliaSousa"};String[]cpfs={"111.111.11111","222.222.22222"};String[]categorias={"Administrativo","Terceirizado"};float[]salarios={4500,2500};Funcionariofuncionario=null;for(inti=0;i
-
Osmtodosdeletarealterarpodemserinvocadosdamesmaformaqueomtodo
salvar,executandoinstruesdeupdateedeleterespectivamente.
AsoluoORMdoHibernateapresentasecomoumatcnicacompletaquetorna
bemmaissimpleseclarooprocessodepersistnciadedados.Atcnicadispensao
usodemtodoscomopreparedStatement,responsveisportornarosmtodospara
execuodeoperaesCRUDextensosededifcilcompreenso.Almdisso,o
Hibernatepossibilitaareduoconsiderveldaquantidadedecdigonas
aplicaes.
Links
Bauer,ChristianKing,GavinHIBERNATEEMAO.Ed.CinciaModernaLtda.Rio
deJaneiro,2005.ISBN8573934042.
PERSISTINDOOSDADOSCOMOHIBERNATE.
http://www.caelum.com.br/apostilavraptorhibernate/persistindoosdadoscomohibernate/
HIBERNATEREFERENCEDOCUMENTATION
https://docs.jboss.org/hibernate/orm/3.5/reference/en/html
Luckow,DcioH.eMelo,AlexandreA.PROGRAMAOJAVAPARAWEB.Ed.
Novatec.SoPaulo,2010.ISBN9788575222386.
POSTGRESQL
http://postgresql.org
HIBERNATE
http://www.hibernate.org
SLF4J
http://www.slf4j.org
JDBCdoPostgreSQL
https://jdbc.postgresql.org/
ECLIPSE
http://www.eclipse.org/downloads/
-
Gostei(2) (0)
Oquevocachoudestepost?
Postardvida/Comentrio
AnaPatriciaDeSousa
GraduandaemAnliseeDesenvolvimentodeSistemasIFPITcnicaemLogsticaSenac/PI
Todososcomentarios(3)Meuscomentarios
FlavioMorigi
Estoutentandomontaroprojeto,masnoencontreiospacotes"jta1.1.jar"enemo"lucenecore4.10.4.jar".Estouutilizandoospacotesmaisrecentes(versoestvel)doslinksindicados:
hibernaterelease4.3.10.Final.zipslf4j1.7.12.zippostgresql9.31103.jdbc3.jar
[h4dias]Responder
[autor]AnaPatriciaDeSousaBoanoite!
Osarquivosestodisponveispradownloadnesteslinks:
http://mvnrepository.com/artifact/javax.transaction/jta/1.1
http://mvnrepository.com/artifact/org.apache.lucene/lucenecore
[h4dias]Responder
FlavioMorigi
Muitoobrigado.
[h2dias]Responder
MVP
MVP
-
Publicidade
Servios
Incluaumcomentrio
AdicionaraosFavoritos
Marcarcomolido/assistido
Incluiranotaopessoal
Versoparaimpresso
+Java
Mais postsVideo aula
Otimizao de memria - Curso de Java Avanado - Aula 8
Video aula
Medindo Memria no Java - Curso de Java Avanado - Aula 7
-
Video aula
Java Debugger - Curso de Java Avanado - Aula 6
Video aula
Decompilao e Ofuscao - Curso de Java Avanado - Aula 5
Video aula
Bytecode, Unassembler e cmd - Curso de Java Avanado -Aula 4
Video aula
Comandos e Bytecode - Curso de Java Avanado - Aula 3
Video aula
Arquitetura Java - Curso de Java Avanado - Aula 2
Video aula
Introduo ao Java Avanado - Curso de Java Avanado -Aula 1
Artigo
Trabalhando com o Design Pattern Interceptor no Java EE
Listar mais contedo
Anuncie | Loja | Publique | Assine | Faleconosco
-
HospedagemwebporPorta80WebHosting
DevMedia
67.790pessoascurtiramDevMedia.
PluginsocialdoFacebook
Curtir