Você está na página 1de 19

Acessando banco de dados em Java (PARTE 1)

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.

Statement stm = con.createStatement();

// 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

20. 21. 22.

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. {

62. 63. 64. 65. 66.

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.

Acessando Banco de Dados em Java (PARTE 2)


Publicado por daltoncamargo em 23/03/2010 177.597 visualizaes As chamadas de JDBC No artigo passado, mostramos o primeiro exemplo de acesso a um banco de dados com JDBC. Neste artigo comearemos a explicar alguns motivos implementados no padro utilizando o exemplo do artigo passado. O que nos chama a ateno logo de cara que o cdigo JDBC no se assemelha ao que o programador iniciante em Java est acostumado. Por exemplo, fazemos: 1. Connection con = DriverManager.getCon nection(parametros da conexo); ao invs de 1. Connection con = new Connection(); JDBC um padro onde est definida uma estrutura geral de acesso ao driver de banco de dados atravs de interfaces e o fornecedor se encarrega de implementar as classes que concretamente vo realizar o servio. Ora, cada fornecedor tem o seu driver especfico, Quote: DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); para Oracle 8i construdo como uma classe JDBC. A chamada funo forName(classe) registra a classe nomeada na JVM corrente: Quote: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver" ).getInstance(); o Sun JDBC-ODBC bridge

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:

O comportamento do driver JDBC uma incgnita. Depende sobretudo da arquitetura de

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.

Acessando Banco de Dados em Java (PARTE 3)


Publicado por daltoncamargo em 28/08/2009 143.261 visualizaes
A interface Connection Como o exemplo anterior (Acessando Bancos de Dados em Java - PARTE 2) demonstrou, as interfaces fundamentais para obter acesso a um repositrio de dados em Java so: 1. Connection 2. Statement e suas PreparedStatement CallableStatement 3. ResultSet variantes: e um repositrio de dados seja adiada para o momento da execuo, aps o JDBC Driver que possibilita o acesso ser registrado em DriverManager. Desta forma, cada objeto na cadeia de execuo de JDBC cria o seu sucessor na cadeia. Ou seja: DriverManager -> Connection -> Statement (ou variantes) -> ResultSet Connection pode criar Statement, PreparedStatement e CallableStatement atravs de um conjunto de chamadas: createStatement() -> cria uma instncia de Statement para execuo de SQL no repositrio createStatement(tipo de cursor, concorrncia) -> idem ao anterior, especificando o tipo de cursor a criar e o nivel de concorrncia da conexo. Antes da verso 2.0, s se podia conectar um banco de dados JDBC com cursores unidirecionais. Isto , uma aplicao que lia a linha 1 e em seguida a linha 2 da tabela no podia retornar linha 1 sem estabelecer um novo result set. A partir da verso 2, se o repositrio de dados suportar esta caracterstica, podemos estabelecer cursores bidirecionais de dois tipos: sensiveis, em que as

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.

Acessando dados com Java: 1 parte - Simples Dao


Publicado por jesuino em 02/05/2012 - 292.853 visualizaes Esse tutorial pretende mostrar como operaes como busca, deleo, atualizao e insero de dados no banco podem ser feitas com diversas tecnologias. Assim, podemos ter um repositrio de tutorias sobre as mais diversas API's, tecnologias e frameworks que esto no mundo Java com um exemplo simples e de fcil entendimento. Embora aqui no frum tenhamos muitos tutoriais com acesso a banco de dados, esse pretende ser um pouco diferente, pois iremos utilizar as classes demonstradas hoje para construir outras partes em outras tecnologias. Primeiramente parte iremos abordar somente o banco de dados e a manipulao dos dados em modo texto. Futuramente, pretendemos usar essas mesmas classes com Java Swing entre outras tecnologias. Por ser um primeiro exemplo simples, essa primeira parte desconsiderou algumas boas prticas e uso de alguns comandos um pouco mais complexos, e quebramos alguns padres, como exibio de mensagem ser da responsabilidade da view. Assim, na segunda parte iremos mostrar como deixar o acesso mais limpo e flexvel, eliminando muitos pontos fracos do cdigo! Sem papo, o aplicativo Primeiro vamos definir o que iremos tratar, que tal uma pessoa? Ok, pessoa!! Nossa pessoa precisa se identificar, RG! Mas voc no chama as pessoas pelo RG, ento colocaremos o nome da pessoa tambm e mais estado, cidade, idade e s. Toda tabela precisa de um identificador nico que chamamos de chave primria, ou seja, algo que diferencie uma tabela das outras. No caso da pessoa, a chave o RG. Agora vamos criar isso no banco de dados, estamos usando MySql. Dvidas com a instalao do MySQL? Criamos um database com o nome "javafx_crud"(voc pode criar com o nome que

quiser), o script para a criao da tabela ficou assim:

7. 8.

estado varchar(2) not null, primary key(rg) 9. 9. );

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!

Lembre-se de incluir o JAR no seu projeto para o driver do MySQL!!

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. }

34. 35. { 36. 37.

public Vector<Pessoa> buscarTodos()

72. 73. 74.

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

"um pontap" para aprendizado.

Acessando Dados com Java: Parte 2 - Prevendo problemas


Publicado por jesuino em 17/08/2009 - 57.449 visualizaes Nessa parte vamos abordar pontos que deixaram a desejar na parte anterior. Melhorar o que? O proposto no artigo anterior funciona! Sim funciona! No entanto, vamos abordar detalhadamente o que pode ocorrer. Observe que muitas coisas dependem da opinio e experincia do desenvolvedor, e por muitas vezes a soluo encontrada no a ideal, assim, alguns pontos no final desse artigo tambm so passveis de evoluo. 1-) Chave primria da tabela pessoa: Usamos como Chave primria o campo RG da tabela. Realmente identifica a tabela unicamente, mas pode gerar problemas futuros. necessrio termos uma chave nica, que identifica pelo sistema. Assim podemos controlar a tabela unicamente sem depender da abstrao que foi feita. Um problema real que pode ocorrer se nos requisitos do programa o RG no for um atributo desejada para a entidade em questo. claro que isso pode ocorrer com qualquer outro campo, mas com nossa chave os problemas so maiores, pois perdemos a identificao dessa tabela no sistema em si. Enfim, uma nova chave, com nmero no interessante para que usa o sistema, que far que o sistema identifique cada entidade independente do que est modulando. Na prtica usaremos uma chave com incremento automtico, que nunca pode ser nula: 1. CREATE TABLE pessoa ( 2. id int(4) not null auto_increment, 3. rg varchar(20) not null, 4. nome varchar(20) not null, 5. idade int(2) not null, DAO significa Data Access Object. um padro criado pela Sun que prega a separao de acesso aos dados da lgica de negcio (business logic) e disponibiliza uma interface abstrata de persistncia a dados independente do banco utilizado. Bem simples e diretamente, sem se aprofundar: temos que ter uma classe de acesso aos dados. Conforme viram, acesso! Somente com as definies acima possvel ver que quebramos esse padro na implementao anterior. Vamos enumerar e falar brevemente o que est fora do padro no nosso caso. - Exibir mensagem de erro: Temos um mtodo que faz a exibio do erro(imprimeErro) que fica na DAO. A comunicao com o usurio deve ser feita pela View, afinal, esse o objetivo dessa camada. Conforme j dito, DAO serve para acessar dados, no exibir mensagem. O melhor a ser feito nesse caso "passar a bola", ou seja, lanar a exceo. Para isso usamos o comando throw. Usando throws: 1. public ... throws Exception 6. cidade varchar(20) not null, 7. estado varchar(2) not null, 8. primary key(id) 9. ); O auto_increment quer dizer que a cada pessoa acessada esse nmero ter seu valor adicionado em um sobre o ltimo valor adicionado. Ou seja, se eu adicionar uma pessoa "Jos", ele ter o id com valor 1, e adicionar "Maria" logo depois, ela ter o id com valor 2 e assim segue conforme vamos adicionando novas pessoas. 2-)DAO DAO!

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.

Acessando Dados com Java: Parte 3 - Hibernate Annotations


Publicado por jesuino em 23/06/2011 165.224 visualizaes Acompanhe a parte 1(apresentao de um simples, mas defeituoso, acesso a dados usando JDBC) e a parte 2(Possveis melhorias para a parte 1).

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.

<property name="connection.passw ord">senha</property>

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;

13. <!--JDBC connection pool (use the built-

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

Você também pode gostar