Escolar Documentos
Profissional Documentos
Cultura Documentos
Publicado por daltoncamargo 17/08/2009 - 834.426 visualizaes em implementadas em linguagem C e compiladas para Wintel, ou outra plataforma ODBC compatvel, as chamadas funes nativas. - O driver tipo 2 implementado parcialmente em Java e parcialmente atravs de funes nativas que implementam alguma API especfica do fornecedor de banco de dados. Este tipo faz o que se chama de wrap-out, ou seja, prov uma interface Java para uma API nativa no-Java. - O tipo 3 um driver totalmente Java que se comunica com algum tipo de middleware que ento se comunica com o banco de dados - O tipo 4 um driver totalmente Java que vai diretamente ao banco de dados. Numa prxima parte veremos ainda um driver gratuito que permite acessar bancos de dados que ofeream suporte apenas ao Bridge (tipo 1) via rede. Veremos a seguir como acessar um banco de dados atravs de JDBC. Nosso cenrio bsico uma pequena aplicao de controle dos meus CDs (clssica !) implementada em algum xBase compatvel. Em prximos exemplos iremos utilizar outros bancos de dados. Para utilizarmos a JDBC num programa em Java, precisamos declarar o pacote que contm a JDBC API: Acessando bancos de dados em JDBC 1. import java.sql.*; A primeira coisa a fazer estabelecer uma conexo com o banco de dados. Fazemos isso em dois passos: primeiro carregamos o driver para o banco de dados na JVM da aplicao (1). Uma vez carregado, o driver se registra para o DriverManager e est disponvel para a aplicao. Utilizamos ento a classe DriverManager para abrir uma conexo com o banco de dados (2). A interface Connection
Uma funcionalidade essencial em qualquer sistema a habilidade para comunicarse com um repositrio de dados. Podemos definir repositrio de dados de vrias maneiras, por exemplo, como um pool de objetos de negcio num ORB ou um banco de dados. Bancos de dados constituem o tipo mais comum de repositrio. Java dispe de uma API para acessar repositrios de dados: a Java DataBase Connectivity API ou JDBC API. A JDBC implementa em Java a funcionalidade definida pelo padro SQL Call Level Interface ou SQLCLI. Um outro exemplo de API que implementa o SQL Call Level Interface o popularssimo ODBC das plataformas Wintel. A maioria dos fornecedores de bancos de dados oferece uma implementao particular de SQLCLI. A vantagem de JDBC a portabilidade da aplicao cliente, inerente da linguagem Java. A especificao corrente da JDBC API a 2.1. A JDBC compreende uma especificao para ambos: os desenvolvedores de drivers JDBC e os desenvolvedores de aplicaes clientes que precisem acessar bancos de dados em Java. Estaremos dando uma olhada no desenvolvimento de aplicaes em Java, ento, uma boa idia comear com o suporte de dados. Existem 4 tipos de diferentes de drivers JDBC (para uma lista de fornecedores por especificao e tipo, vide http://www.javasoft.com/products/jdbc/drivers.ht ml ) - Uma vez que ODBC uma especificao padro do mundo Wintel, o tipo 1 um driver de ponte entre Java e ODBC. O driver de ponte mais conhecido o fornecido pela Sun o JDBCODBC bridge. Este tipo de driver no portvel, pois depende de chamadas a funes de ODBC
designa um objeto, no caso con, para receber a conexo estabelecida: 1. try //A captura de excees SQLExcept ion em Java obrigatria para usarmos J DBC. 2. { 3. // Este um dos meios para registrar um driver 4. Class.forName("sun.jdbc.odbc.Jdbc OdbcDriver").getInstance(); 5. 6. // Registrado o driver, vamos estabel ecer uma conexo 7. Connection con = DriverManager.get Connection("jdbc:odbc:meusCdsDb","co nta","senha"); 8. } 9. catch(SQLException e) 10. { 11. // se houve algum erro, uma exceo gerada para informar o erro 12. e.printStackTrace(); //vejamos que er ro foi gerado e quem o gerou 13. } Estabelecida a conexo, podemos executar comandos SQL para o banco de dados. Vejamos como realizar uma consulta sobre o ttulo, numero de faixas e o artista de cada CD no banco de dados. Podemos usar 3 interfaces para executar comandos SQL no banco de dados. A primeira delas a interface Statement, que permite a execuo dos comandos fundamentais de SQL (SELECT, INSERT, UPDATE ou DELETE). A interface PreparedStatement nos permite usufruir de SQL armazenado ou prcompilado no banco, quando o banco de dados suportar este recurso. A terceira interface CallableStatement, e permite executar procedimentos e funes armazenados no banco quando o banco suportar este recurso. Vejamos como utilizar a interface Statement. Nos prximos artigos sobre JDBC iremos investigar as outras. 1. // Aps estabelecermos a conexo com o banco de dados 2. // Utilizamos o mtodo createStatement de con para criar o Statement
3. 4. 5.
// Vamos executar o seguinte comando SQL : 6. String SQL = "Select titulo, autor, total _faixas from MeusCDs"; A interface ResultSet permite colher os resultados da execuo de nossa query no banco de dados. Esta interface apresenta uma srie de mtodos para prover o acesso aos dados: 1. // Definido o Statement, executamos a q uery no banco de dados 2. ResultSet rs = stm.executeQuery(SQL); 3. 4. // O mtodo next() informa se houve res ultados e posiciona o cursor do banco 5. // na prxima linha disponvel para recu perao 6. // Como esperamos vrias linhas utiliza mos um lao para recuperar os dados 7. while(rs.next()) 8. { 9. // Os mtodos getXXX recuperam os dados de acordo com o tipo SQL do dado : 10. String tit = rs.getString("titulo"); 11. String aut = rs.getString("autor"); 12. int totalFaixas = rs.getInt("total_faixa s"); 13. 14. // As variveis tit, aut e totalFaixas co ntm os valores retornados 15. // pela query. Vamos imprim-los 16. 17. System.out.println("Titulo: "+tit+" A utor: "+aut+" Tot. Faixas: "+totalFaixas); 18. } E nosso acesso est terminado. O importante agora liberar os recursos alocados pelo banco de dados para a execuo deste cdigo. Podemos fazer isso fechando o Statement, que libera os recursos associados execuo desta consulta mas deixa a conexo aberta para a execuo de uma prxima consulta, ou fechando diretamente a conexo, que encerra
a comunicao com o banco de dados. Para termos certeza de que vamos encerrar esta conexo mesmo que uma exceo ocorra, reservamos o fechamento para a clusula finally() do tratamento de excees. 1. 2. 3. 4. 5. 6. 7. 8. 9. finally { try { con.close(); } catch(SQLException onConClose) { System.out.println("Houve erro no fechamento da conexo"); 10. onConClose.printStackTrace(); 11. } 12. } Uma classe para listar uma tabela Vamos colocar tudo isso em conjunto para termos uma viso em perspectiva: 1. package wlss.jdbcTutorial; 2. 3. import java.sql.*; 4. 5. class Exemplo1 6. { 7. 8. public static void main(String args[]) 9. { 10. 11. 12. // A captura de excees SQLExcepti on em Java obrigatria para usarmos JD BC. 13. // Para termos acesso ao objeto con, el e deve ter um escopo mais amplo que o bl oco try 14. 15. Connection con = null; 16. 17. try 18. { 19. // Este um dos meios para registra r um driver
Class.forName("sun.jdbc.odbc.Jdb cOdbcDriver").getInstance();
// Registrado o driver, vamos estab elecer uma conexo 23. con = DriverManager.getConnectio n("jdbc:odbc:meusCdsDb","conta","senh a"); 24. 25. // Aps estabelecermos a conexo c om o banco de dados 26. // Utilizamos o mtodo createState ment de con para criar o Statement 27. Statement stm = con.createStateme nt(); 28. 29. // Vamos executar o seguinte coma ndo SQL : 30. String SQL = "Select titulo, autor, t otal_faixas from MeusCDs"; 31. 32. // Definido o Statement, executamo s a query no banco de dados 33. ResultSet rs = stm.executeQuery(S QL); 34. 35. // O mtodo next() informa se houv e resultados e posiciona o cursor do banc o 36. // na prxima linha disponvel para recuperao 37. // Como esperamos vrias linhas uti lizamos um lao para recuperar os dados 38. while(rs.next()) 39. { 40. 41. // Os mtodos getXXX recupera m os dados de acordo com o tipo SQL do dado: 42. String tit = rs.getString("titulo"); 43. String aut = rs.getString("autor"); 44. aixas"); 45. 46. // As variveis tit, aut e totalFaixa s contm os valores retornados 47. // pela query. Vamos imprim-los 48. int totalFaixas = rs.getInt("total_f
49.
System.out.println(48:"Titulo: "+ tit+" Autor: "+aut+"49: Tot. Fai xas: "+totalFaixas); 50. } 51. 52. } 53. catch(SQLException e) 54. { 55. // se houve algum erro, uma exce o gerada para informar o erro 56. e.printStackTrace(); //vejamos que erro foi gerado e quem o gerou 57. } 58. finally 59. { 60. try 61. {
con.close(); } catch(SQLException onConClose) { System.out.println("Houve erro n o fechamento da conexo"); 67. onConClose.printStackTrace(); 68. } 69. } // fim do bloco try-catch-finally 70. } // fim da main 71. 72. } // fim de nosso primeiro exemplo ! Na prxima parte deste artigo iremos analisar as extenses introduzidas pela API 2.1 e as interfaces PreparedStatement e CallableStatement.
Quote: Class.forName("COM.ibm.db2.jdbc.net.DB2Dri ver").newInstance(); para o IBM DB2 podemos ainda utilizar o mtodo registerDriver da classe DriverManager para isso:
acesso oferecida pelo banco de dados. Por exemplo, alguns bancos de dados vo exigir uma conexo com um cliente local. Outros utilizam arquivos de configurao. Para tratar com as diferenas entre os diversos produtos, DriverManager utiliza o padro Factory Method para instanciar Connection. Este padro utilizado por todas as interfaces de JDBC. Por exemplo: 1. Connection con = DriverManager.getCon nection("jdbc:odbc:meusCdsDb","conta", "senha"); 2. 3. Statement stm = con.createStatement(); 4. 5. ResultSet rs = stm.executeQuery(alguma query SQL); O problema simplesmente este: no sabemos, em tempo de compilao, qual a estrutura de classe ter a classe do driver que DriverManager ir carregar. Isto feito dinamicamente, no momento em que o driver registrado com DriverManager. Usando o padro FactoryMethod a necessidade de verificar a estrutura do driver estaticamente transformada numa chamada padro de funo que pode ser realizada em tempo de execuo. As classes que implementam concretamente essas interfaces no DB2, por exemplo, so DB2Connection, DB2Statement e DB2ResultSet e esto presentes no pacote db2java.zip. Para os programadores migrados de outros padres, este padro equivalente, no mundo dos objetos, s funes callback, to comuns nos SDKs do Windows. A diferena que um callback registra uma funo a ser chamada. O FactoryMethod cria um objeto. Se voc deseja saber mais sobre o padro FactoryMethod, recomendo "Design Patterns: Principles of Reusable Object Oriented Software" de Erich Gamma e outros. Java Morrendo ??
Uma pergunta lanada numa lista de discusso nos ultimos dias me deixou realmente intrigado. Algum afirmou que a Microsoft estava parando o desenvolvimento em Java (provavelmente devido recente deciso judicial no caso Sun X Microsoft) e perguntou se por causa disso Java no estaria morrendo. A resposta (que continua sendo postada) foi um sonoro NO. Os argumentos variaram desde os motivos religiosos, tipo "M$ Jamais", at decises bem pensadas tipo "...adivinhe quantas companhias esto desenvolvendo uma JVM para a plataforma Wintel neste momento ?". Eu tenho minha humilde opinio a respeito. A aceitao e compromisso do mercado em relao a Java deve-se a diversos fatores: 1. Claramente h uma profunda mudana de viso sobre como construir sistemas em andamento no mercado. O modelo cliente-servidor apoiado na plataforma Wintel dispendioso, difcil de manter e no se ajusta s necessidades do mundo Internet. Ir desaparecer ? No, certamente que no, mas ir sendo posicionado num nicho ao invs de ser utilizado como uma soluo universal. O modelo Internet veio para ficar e mandar. 2. Java permite economia em escala quando seu modelo de portabilidade bem utilizado. Mesmo em ambientes com padres pblicos e conhecidos, como C+ +, portar cdigo um desafio. Em outros ambientes ainda mais populares e mais conhecidos, portar cdigo varia entre o impossvel e o pesadelo. Empresas como a PointBase, de bancos de dados pervasivos, esto, nas palavras de seu CEO: "...empregando mais engenheiros de portabilidade de cdigo que a Oracle, sem gastar um tosto na folha de pagamentos com isso. Onde esto eles ? Na Sun, Na IBM, Na HP..." (JDJ dez/2002). 3. Players pesados esto jogando neste mercado. Nomes como IBM, Oracle, HP, Inprise, (que, ao que parece, agora vai com tudo para o mercado Linux), o Apache.org e a prpria Sun, para citar
alguns, deixam o desenvolvedor e o empresrio bastante tranqilos quanto a seu futuro. Linux ainda incipiente em relao a Java, mas a oferta de JVMs da IBM parece estar surtindo efeito tambm nesta plataforma. 4. XML vem com um modelo de representao de informao que, pela primeira vez, oferece um meio a baixo custo de expressar estruturas de dados complexas com a certeza de que sero lidas onde quer que sejam necessrias. A portabilidade dos dados demanda
portabilidade do cdigo para sua interpretao, pois, como dito no item dois, manter portabilidade custa caro. Java tem uma proposta bastante interessante neste campo. Portanto, Java j ultrapassou a fronteira de sustentao que separa produtos de plataformas. O mximo que pode acontecer agora, IMHO, a linguagem se estabelecer num nicho e a ficar para sempre. Lembram do velho e bom FORTRAN ? Passa muito bem, obrigado.
A Interface Connection responsvel por manter a conexo estabelecida com o repositrio de dados atravs da chamada a DriverManager.getConnection(). A interface Connection tem 3 responsabilidades essenciais: criar ou preparar statements (sentenas SQL), executar o controle de transaes com o repositrio e criar objetos DatabaseMetaData, que permitem pesquisar dinamicamente que capacidades esto presentes no repositrio de dados. Recapitulando, vimos que a API JDBC usa o padro de chamada FactoryMethod, para possibilitar que a criao dos diversos objetos de controle de uma transao com
alteraes havidas previamente na linha so refletidas na releitura, ou insensveis, em que as alteraes havidas na linha no se refletem na releitura. O tipo de cursor que o repositrio suporta uma informao retornada por DatabaseMetadata. O controle de transaes compreende basicamente 3 grupos de funes: getAutoCommit() e setAutoCommit(boolean toSet) -> permitem examinar ou definir que cada solicitao ao banco tenha commit imediato. getTransactionIsolation() e setTransactionIsolation(int transIso) -> permitem examinar ou definir com que
tipo de isolamento de transaes aquela conexo deve operar. commit() e rollback() -> se o banco no est em modo autocommit, commit confirma a transao no banco enquanto que rollback cancela as alteraes da transao.
Um grupo de funes pouco explorado da interface Connection o grupo que trata de ResultSets read-only, composto das funes isReadOnly() e setReadOnly(boolean setRead). Estas funes permitem estabelecer trancas de apenas leitura no banco de dados, evitando que o banco seja saturado por trancas de escrita (trancas de bloqueio), o que permite uma maior concorrncia no acesso ao banco.
7. 8.
1. use javafx_crud; 2. create table pessoa( 3. rg varchar(20) not null, No estamos usando trigramao, afinal temos 4. nome varchar(20) not null, somente uma entidade(tabela)... :S 5. idade int(2) not null, 6. cidade varchar(20) not null, Rodando o Script voc ter sua tabela no banco de dados fisicamente. Sugesto: Usem MySql e MySql Front
Para salvar os dados voc tem que logar no banco e ir inserindo usando o comando INSERT, ou pela interface que os SGBDs(programa que gerencia o banco) oferecem. Mas isso no usual, o interessante ter um aplicativo que faz isso, acessa o banco e permite as funcionalidades, sem o usurio conhecer o banco de dados. Em Java, como em qualquer outra linguagem(exceto algumas especficas, como ABAP, mas isso j so outros 500), voc tem que se conectar ao banco de dados para realizar aes com os dados. Dependendo do banco que voc utiliza, existe um .jar que permite o acesso. O JAR para o MySQL est anexo! Quanto a manipulao, voc pode usar um framework(ex: Hibernate, neste caso at a
conexo) de persistncia ou a soluo nativa de java JDBC. JDBC menos flexvel que um framework, mas mais simples para nosso projetinho, vamos usar JDBC! Crie um projeto Java no eclipse , chame como quiser :), depois comece a codificao! Hora de cdigo O comum em Java criarmos classes Pojo, classes que so semelhantes a tabelas do banco, assim podemos manipular de forma igual para igual ao que est no banco. Nossa classe pessoa: 1. package model; 2. 3. public class Pessoa { 4. private String rg; 5. private String nome;
6. private int idade; 7. private String estado; 8. private String cidade; 9. 10. public void setRg(String rg) { 11. this.rg = rg; 12. } 13. 14. public void setNome(String nome) { 15. this.nome = nome; 16. } 17. 18. public void setIdade(int idade) { 19. this.idade = idade; 20. } 21. 22. public void setEstado(String estado) { 23. this.estado = estado; 24. } 25. 26. public void setCidade(String cidade) { 27. this.cidade = cidade; 28. } 29. 30. public String getRg() { 31. return this.rg; 32. } 33. 34. public String getNome() { 35. return this.nome; 36. } 37. 38. public int getIdade() { 39. return this.idade; 40. } 41. 42. public String getEstado() { 43. return this.estado; 44. } 45. 46. public String getCidade() { 47. return this.cidade; 48. } 49. } Claro, todos os atributos esto encapsulados, nunca use atributo pblico, use sempre mtodos de acesso a atributos declarados como privados. Essa classe parte de um projeto MVC, ela o modelo, ou model, por isso estar no
pacote(usamos para dividir nosso projeto melhor) model, ento crie um pacote e coloque esse cdigo em um arquivo .java l. importante a diviso de papis: quem Model, Control e View, assim podemos usar o que for definido hoje nos projetos futuros. Agora vamos implementar a parte de banco de dados, meio chato mais temos que fazer. Para a conexo temos uma classe que faz a funo de fbrica de conexes. Isso mesmo, o padro Factory que usamos em um projeto muito antigo, mas serve para esse da mesma forma. Obeserve que para outros bancos de dados voc deve alterar a fbrica, essa s tem a parte do MySql. Essa classe foi alocada no pacote "banco", ento no perca tempo e crie o pacote "banco"(que estar em outro pacote futuramente, o dao). 1. package dao.banco; 2. 3. import java.sql.Connection; 4. import java.sql.DriverManager; 5. import java.sql.SQLException; 6. 7. public class ConFactory { 8. 9. public static final int MYSQL = 0; 10. private static final String MySQLDriver = "com.mysql.jdbc.Driver"; 11. 12. public static Connection conexao(Strin g url, String nome, String senha, 13. int banco) throws ClassNotFoundE xception, SQLException { 14. switch (banco) { 15. case MYSQL: 16. Class.forName(MySQLDriver); 17. break; 18. } 19. return DriverManager.getConnection( url, nome, senha); 20. } 21. } Perceba que a classe lana um exceo quando algo da errado na conexo com o banco, e muita coisa pode dar errado!
Clique com o boto direito em cima do seu projeto, escolha propriedade. Na janela propriedades, escolha JavaBuild Path, clique em Add JARs ou Add External JARs: Para acessar os dados usamos o padro DAO, assim encapsulamos todo o trabalho com o banco, e nossas classes que querer usar e manipular os dados simplesmente devem conhecer nossa classe DAO, sem se preocupar com abrir conexo, fechar e inserir comandos. Olhem nossa classe de acesso, percebam que ela permite todas operaes com a tabela Pessoa(Est no pacote dao): 1. package dao; 2. 3. import java.sql.Connection; 4. import java.sql.ResultSet; 5. import java.sql.SQLException; 6. import java.sql.Statement; 7. import java.util.Vector; 8. 9. import javax.swing.JOptionPane; 10. 11. import model.Pessoa; 12. import dao.banco.ConFactory; 13. 14. public class DaoPessoa { 15. // Configura essas variveis de acordo c om o seu banco 16. private final String URL = "jdbc:mysql: //localhost/javafx_crud", 17. NOME = "root", SENHA = "senha" ; 18. 19. private Connection con; 20. private Statement comando; 21. 22. public void apagar(String rg) { 23. conectar(); 24. try { 25. comando 26. .executeUpdate("DELETE FRO M pessoa WHERE rg = '" + rg 27. + "';"); 28. } catch (SQLException e) { 29. imprimeErro("Erro ao apagar pesso as", e.getMessage()); 30. } finally { 31. fechar(); 32. } 33. }
conectar(); Vector<Pessoa> resultados = new Ve ctor<Pessoa>(); 38. ResultSet rs; 39. try { 40. rs = comando.executeQuery("SELE CT * FROM pessoa"); 41. while (rs.next()) { 42. Pessoa temp = new Pessoa(); 43. // pega todos os atributos da pesso a 44. temp.setRg(rs.getString("rg")); 45. temp.setNome(rs.getString("nome ")); 46. temp.setIdade(rs.getInt("idade")); 47. temp.setCidade(rs.getString("cida de")); 48. temp.setEstado(rs.getString("esta do")); 49. resultados.add(temp); 50. } 51. return resultados; 52. } catch (SQLException e) { 53. imprimeErro("Erro ao buscar pesso as", e.getMessage()); 54. return null; 55. } 56. } 57. 58. public void atualizar(Pessoa pessoa) { 59. conectar(); 60. String com = "UPDATE pessoa SET nome = '" + pessoa.getNome() 61. + "', idade =" + pessoa.getIdade() + ", cidade = '" 62. + pessoa.getCidade() + "', estado ='" + pessoa.getEstado() 63. + "' WHERE rg = '" + pessoa.get Rg() + "';"; 64. System.out.println("Atualizada!"); 65. try { 66. comando.executeUpdate(com); 67. } catch (SQLException e) { 68. e.printStackTrace(); 69. } finally { 70. fechar(); 71. }
public Vector<Pessoa> buscar(String rg ){ 75. conectar(); 76. Vector<Pessoa> resultados = new Ve ctor<Pessoa>(); 77. ResultSet rs; 78. try { 79. rs = comando.executeQuery("SELE CT * FROM pessoa WHERE rg LIKE '" 80. + rg + "%';"); 81. while (rs.next()) { 82. Pessoa temp = new Pessoa(); 83. // pega todos os atributos da pesso a 84. temp.setRg(rs.getString("rg")); 85. temp.setNome(rs.getString("nome ")); 86. temp.setIdade(rs.getInt("idade")); 87. temp.setCidade(rs.getString("cida de")); 88. temp.setEstado(rs.getString("esta do")); 89. resultados.add(temp); 90. } 91. return resultados; 92. } catch (SQLException e) { 93. imprimeErro("Erro ao buscar pesso a", e.getMessage()); 94. return null; 95. } 96. 97. } 98. 99. public void insere(Pessoa pessoa){ 100. conectar(); 101. try { 102. comando.executeUpdate("I NSERT INTO Pessoa VALUES('" 103. + pessoa.getRg() + "', '" + pessoa.getNome() + "'," 104. + pessoa.getIdade() + ",' " + pessoa.getCidade() + "','" 105. + pessoa.getEstado() + "' )"); 106. System.out.println("Inserida !"); 107. } catch (SQLException e) {
108. imprimeErro("Erro ao inseri r Pessoa", e.getMessage()); 109. } finally { 110. fechar(); 111. } 112. } 113. 114. private void conectar() { 115. try { 116. con = ConFactory.conexao( URL, NOME, SENHA, ConFactory.MY SQL); 117. comando = con.createStatem ent(); 118. System.out.println("Conecta do!"); 119. } catch (ClassNotFoundExcep tion e) { 120. imprimeErro("Erro ao carre gar o driver", e.getMessage()); 121. } catch (SQLException e) { 122. imprimeErro("Erro ao conec tar", e.getMessage()); 123. } 124. } 125. 126. private void fechar() { 127. try { 128. comando.close(); 129. con.close(); 130. System.out.println("Conex o Fechada"); 131. } catch (SQLException e) { 132. imprimeErro("Erro ao fecha r conexo", e.getMessage()); 133. } 134. } 135. 136. private void imprimeErro(String msg, String msgErro) { 137. JOptionPane.showMessageDi alog(null, msg, "Erro crtico", 0); 138. System.err.println(msg); 139. System.out.println(msgErro); 140. System.exit(0); 141. } 142. } Eu, particularmente, costumo criar classes que herdam de um pai(ou implementam uma
interface) DAO, para evitar repetir cdigo, mas como temos somente uma tabela(entidade para alguns) iremos usar esse DAO especfico, o DaoPessoa. Quanto ao cdigo no temos segredo. Primeiro conectamos, com nossa conexo criamos um comando. Depois do comando enviamos uma String que corresponde ao comando de banco de dados(como o DELETE, INSERT, SELECT e UPDATE). Perceba que para cada comando tem um tratamento de exceo, assim identificamos o erro "na lata"! Os nossos mtodos de busca retornam um Vector de pessoas, poderamos utilizar outra estutura de armazenamento mltiplo(Collection), como o ArrayList... Para mostrar o erro usamos um mtodo, assim encapsulamos como o erro ser exibido(pois podemos no querer sair do programa, ou exibir o erro no console ou uma janela de dilogo...), sem problemas! Agora chegou a hora mais interessante, vamos testar o que fizemos at agora: 1. import java.util.Iterator; 2. import java.util.Vector; 3. 4. import model.Pessoa; 5. import dao.DaoPessoa; 6. 7. public class Teste { 8. 9. public static void main(String[] args) { 10. Pessoa pessoa = new Pessoa(); 11. DaoPessoa daoPessoa = new DaoPess oa(); 12. pessoa.setNome("Jos da Silva"); 13. pessoa.setRg("12345678X"); 14. pessoa.setIdade(20); 15. pessoa.setEstado("SP"); 16. pessoa.setCidade("So Paulo"); 17. 18. daoPessoa.insere(pessoa); 19. 20. Vector<Pessoa> resultado = daoPesso a.buscar("12345678X"); 21.
22.
for (Iterator<Pessoa> iterator = result ado.iterator(); iterator 23. .hasNext();) { 24. Pessoa p = iterator.next(); 25. System.out.println("Pessoa Encontr ada: " + p.getNome()); 26. } 27. pessoa.setNome("Jos da Silva Sauro "); 28. 29. daoPessoa.atualizar(pessoa); 30. 31. resultado = daoPessoa.buscar("12345 678X"); 32. 33. for (Iterator<Pessoa> iterator = result ado.iterator(); iterator 34. .hasNext();) { 35. Pessoa p = iterator.next(); 36. System.out.println("Pessoa Encontr ada: " + p.getNome()); 37. } 38. 39. daoPessoa.apagar("12345678X"); 40. 41. resultado = daoPessoa.buscar("12345 678X"); 42. 43. if (resultado.size() == 0) { 44. System.out.println("Pessoa foi apag ada com sucesso"); 45. } else { 46. System.out.println("A pessoa perma nece no banco de dados"); 47. } 48. 49. } 50. } Nada demais neste teste, estamos inserindo uma pessoa, depois buscando para ver se ela foi inserida mesmo! Em seguida atualizamos o nome e buscamos para ver se aconteceu a atualizao, por fim apagamos a pessoa e tentamos realizar a busca para ter certeza que nosso dado foi apagado mesmo! Ao rodar essa classe voc deve obter o seguinte resultado no console:
Quote: Conectado! Inserida! Conexo Fechada Conectado! Pessoa Encontrada: Jos da Silva Conectado! Atualizada! Conexo Fechada Conectado! Pessoa Encontrada: Jos da Silva Sauro Conectado! Conexo Fechada Conectado! Pessoa foi apagada com sucesso Se voc no conseguiu, volte e tente fazer tudo desde o comeo! Chegamos ao fim desse primeiro tutorial, nossas classes ficaram como mostrado abaixo:
No percam a segunda parte, onde mostraremos uma segunda forma de realizar essas mesmas funcionalidade, demonstrando problemas e erros futuros que essa parte poderia apresentar (Obrigado a todos que opinaram e as grandes crticas construtivas)
-WebServices(Oferecer o acesso como um servio) -Uso com algum FrameWork(Struts, JSF...) -Outros...
A idia demonstrar diversas tecnologias com esse exemplo simples, assim teremos
OBS: Como no tnhamos interface grfica, foi mantido o mtodo imprimeErro, no outro tutorial, buscando a simplicidade. E o DAO passa a ser independente de onde executado, ou seja, WEB ou desktop podem usar. Antigamente, somente em casos Desktop(JavaSwing) iramos ver a mensagem(JOptionPane), com throws podemos delegar o tratamento de exceo para quem usa o DAO. - Conectar ao banco de dados: DAO no tem nada a ver com a conexo, a conexo deve ser papel de outra classe, DAO deve permitir a manipulao dos dados, no deve se "envolver" com a impresso de dados e nem com a conexo. Outra coisa, com informaes locais da conexo faz nosso DAO perder a portabilidade e flexibilidade. No nosso caso reformulamos a conexo para conseguir maior flexibilidade. Como j dito, o resultado obtido no o perfeito, muitos podem opinar e melhorar esse resultado! Por fim, o DAO deve o mais genrico possvel! Em alguns pontos omitimos essa abstrao do DAO para conseguir maior simplicidade na hora de expor nosso objetivo, mas tenha em mente sempre deixar as classes DAO flexveis na medida do possvel, ou seja, o que poder ser feito para melhorar a abstrao, FAA! 3-) Cdigo O cdigo deixa muito a desejar em alguns pontos. Sem muito papo, vamos a eles:
-Uso de Statement Absolutamente no est errado, mas o Statement deixa o cdigo sujo, no ajuda na manuteno e nem na visibilidade. Uma outra opo o PrepareStatement, onde: *No precisamos imediatamente colocar as aspas simples que representam String, por exemplo, ele cuida da montagem do SQL. *No necessrio a concatenao da String do comando com os valores. Com somente esses dois argumentos fica claro que o uso de PrepareStatement ao contrrio de Statement mais vantajoso. -Tipo concreto de List invs de tipo abstrato. No retorno do mtodo estvamos usando Vector, um tipo de List. O melhor seria usar o tipo genrico, List, pois no garante maior flexibilidade, conforme j foi dito anteriormente. Cada tipo concreto de List se aplica melhor em determinados casos. Tendo uma List genrica voc pode utilizar o resultado da forma que melhor se aplica a sua necessidade. Concluso: Demonstrou-se melhores prticas e pontos prejudiciais no projeto anterior. Pretendemos montar uma verso melhor para as partes que viro. Aguarde os prximos artigos onde iremos demonstrar o acesso a estes dados usando JavaSwing e outras tecnologias.
Objetivo: Mostrar um exemplo simples de acesso a dados com Java usando Hibernate Annotations. Requerimentos: Para realizar esse tutorial voc deve ter os seguintes JARs no seu projeto(No eclipse, de preferncia), mais o jar para o driver do seu banco de dados utilizado:
Hibernate Annotations permite que voc realize o mapeamento ORM sem utilizar XML, somente Annotations. Para isso voc deve trabalhar com classes POJOs, ou seja, atributos privados, acessados pelos famosos mtodos GET e SET. Crie um pacote model e dentro a seguinte classe anotada: 1. package model; 2. import javax.persistence.*; 3. 4. @Entity 5. @Table(name="PESSOA") 6. public class Pessoa { 7. private int id; 8. private String rg; 9. private String nome; 10. private int idade; 11. private String estado; 12. private String cidade; 13. 14. @Id 15. @GeneratedValue 16. @Column(name="PESSOA_ID") 17. public int getId() { 18. return id; 19. } 20. public void setId(int id) { 21. this.id = id; 22. } 23. 24. @Column(name="PESSOA_RG", null able=false) 25. public String getRg() { 26. return rg; 27. } 28. public void setRg(String rg) { 29. this.rg = rg; 30. } 31. 32. @Column(name="PESSOA_NOME", nullable=false) 33. public String getNome() { 34. return nome; 35. } 36. public void setNome(String nome) { 37. this.nome = nome; 38. } 39.
Baixar Projeto do Eclipse Persistindo Pessoas Iremos utilizar o mesmo exemplo de entidade dos tutoriais anteriores, a entidade pessoa, que ficou como segue: Quote: Pessoa: ID, RG, NOME, IDADE, CIDADE, ESTADO Crie sua tabela no banco de dados. Nesse tutorial foi utilizado MySql como banco de dados, se tambm utilizar MySql, pode criar a tabela com o script abaixo: 1. CREATE TABLE pessoa ( 2. pessoa_id int(11) NOT NULL auto_incr ement, 3. pessoa_rg varchar(20) default NULL, 4. pessoa_nome varchar(20) default NULL , 5. pessoa_idade int(2) default NULL, 6. pessoa_cidade varchar(20) default NUL L, 7. pessoa_estado varchar(2) default NULL , 8. PRIMARY KEY (pessoa_id) 9. )
40. 41. 42. 43. 44. 45. 46. 47. 48. ") 49. 50. 51. 52. 53. 54. 55. 56. )
@Column(name="PESSOA_IDADE") public int getIdade() { return idade; } public void setIdade(int idade) { this.idade = idade; } @Column(name="PESSOA_ESTADO public String getEstado() { return estado; } public void setEstado(String estado) { this.estado = estado; } @Column(name="PESSOA_CIDADE"
@Column: Utilizamos para especificar uma coluna da tabela do banco de dados. No exemplo acima, especificamos que o campo RG e nome . Se voc no mapear a coluna, o nome da propriedade ser usado como nome da coluna.
57. public String getCidade() { 58. return cidade; 59. } 60. public void setCidade(String cidade) { 61. this.cidade = cidade; 62. } 63. } A seguir uma explicao bsica sobre cada anotao: @Entity: Usamos para marcar uma classe como entidade do banco de dados. Esta classe deve estar em um pacote e no ter argumentos em seu construtor. @Table: Essa anotao serve para indicar em qual tabela iremos salvar os dados. Se voc no usar essa anotao, o Hibernate usa o nome da classe para a tabela. O atributo name refere-se ao nome da tabela. @Id: Usamos para mostra o identificador nico(chave primria) de nossa classe persistente. No nosso caso, o identificador nico o campo ID. GeneratedValue:Indica que o valor para o identificador nico ser gerado automaticamente. Voc pode configurar a forma de gerao dos valores atravs do atributor strategy. Se voc no colocar uma estratgia, ser usada a estratgia AUTO.
Configurando a fonte de dados O prximo passo configurar nossa fonte de dados. Nesse ponto usamos mapeamento XML, o nico. Nos iremos adicionar os dados da fonte e as classes mapeadas. Observe bem os parmetros da fonte de dados, essa parte muito comum apresentar erros. Meu XML ficou assim: 1. <?xml version='1.0' encoding='UTF-8'?> 2. <!DOCTYPE hibernate-configuration PU BLIC 3. "-//Hibernate/Hibernate Configuration D TD 3.0//EN" 4. "http://hibernate.sourceforge.net/hibernat e-configuration-3.0.dtd"> 5. 6. <hibernate-configuration> 7. <session-factory> 8. <!--Database connection settings--> <property name="connection.driver_class ">com.mysql.jdbc.Driver</property> 9. <property name="connection.url">j dbc:mysql://localhost:3306/simples_tutor ial_annotations</property> 10. <property name="connection.userna me">root</property>
11. 12.
Agora nos resta testar para verificar se tudo que foi feito at aqui est certo. Uma classe de teste: 1. 2. 3. 4. 5. 6. 7. 8. import model.Pessoa; import org.hibernate.Session; import util.HibernateUtil; import org.hibernate.Transaction;
in)--> 14. <property name="connection.pool_size"> 1</property> 15. 16. <!-- SQL dialect --> 17. <property name="dialect">org.hiber nate.dialect.MySQLDialect</property> 18. 19. <!-- Echo all executed SQL to stdout --> 20. <property name="show_sql">true</ property> 21. 22. <!-- Mapping files --> 23. <mapping class="model.Pessoa"/> 24. </session-factory> 25. </hibernate-configuration> A fbrica de sesses Quem j mexeu com Hibernate conhece muito bem a famosa fbrica de Sesses e a classe HibernateUtil. Crie um pacote chamado util e uma classe chamada HibernateUtil. Abaixo nossa classe HibernateUtil: 1. package util; 2. 3. import org.hibernate.SessionFactory; 4. import org.hibernate.cfg.AnnotationConfi guration; 5. public class HibernateUtil { 6. private static final SessionFactory sessi onFactory; 7. static { 8. sessionFactory = new AnnotationCon figuration().configure() 9. .buildSessionFactory(); 10. } 11. 12. public static SessionFactory getSession Factory() { 13. return sessionFactory; 14. } 15. }
public class Teste { public static void main(String[] args) { Session sessao = HibernateUtil.getSes sionFactory().openSession(); 9. Transaction t = sessao.beginTransaction() ; 10. 11. Pessoa pessoa = new Pessoa(); 12. pessoa.setNome("William"); 13. pessoa.setRg("123456"); 14. pessoa.setCidade("So Jos dos camp os"); 15. pessoa.setEstado("SP"); 16. pessoa.setIdade(21); 17. sessao.save(pessoa); 18. t.commit(); 19. sessao.close(); 20. 21. } 22. }
Perceba que neste teste simplesmente estamos instanciando uma pessoa e inserindo no banco de dados. No h um DAO para abstrair as operaes CRUD para com o banco. O prximo passo criar esse DAO, que possibilitar maior flexibilidade e encapsulamento das operaes com o banco de dados. Concluso Apresentamos uma pequena amostra de persistncia usando Hibernate Annotations. O foco desse tutorial, assim como dos outros, foi a simplicidade. claro que quem conseguir terminar este tutorial no ser o mestre Hibernate Annotations, mas ter um impulso para comear seus estudos.
Esperamos que todos possam usufruir desse tutorial, e lembramos que o frum est aberto para retirada de dvidas e compartilhamento de experincias. Baixar Projeto do Eclipse Futuro
Esse ser o acesso bsico para as prximas partes do nosso tutorial, onde mostraremos como montar interfaces para que um usurio comum possa utilizar-se do sistema. Fonte: Vanilla Hibernate Annotation