Você está na página 1de 41

)

#
APOSTILA JAVA PARA DESENVOLVIMENTO WEB

"

CAPTULO 2

Bancos de dados e JDBC


"O medo o pai da moralidade" Friedrich Wilhelm Nietzsche Ao trmino desse captulo, voc ser capaz de: conectar-se a um banco de dados qualquer atravs da API JDBC; criar uma fbrica de conexes usando o design pattern Factory; pesquisar dados atravs de queries; encapsular suas operaes com bancos de dados atravs de DAO Data Access Object.

2.1 - POR QUE USAR UM BANCO DE DADOS?


Muitos sistemas precisam manter as informaes com as quais eles trabalham, seja para permitir consultas futuras, gerao de relatrios ou possveis alteraes nas informaes. Para que esses dados sejam mantidos para sempre, esses sistemas geralmente guardam essas informaes em um banco de dados, que as mantm de forma organizada e prontas para consultas.

A maioria dos bancos de dados comerciais so os chamados relacionais, que uma forma de trabalhar e pensar diferente ao paradigma orientado a objetos. O MySQL o banco de dados que usaremos durante o curso. um dos mais importantes bancos de dados relacionais, e gratuito, alm de ter uma instalao fcil para todos os sistemas operacionais. Depois de instalado, para acess-lo via terminal, fazemos da seguinte forma:
m y s q lur o o t

Banco de dados Para aqueles que no conhecem um banco de dados, recomendado ler um pouco sobre o assunto e tambm ter uma base de SQL para comear a usar a API JDBC.

O processo de armazenamento de dados tambm chamado de persistncia. A biblioteca de persistncia em banco de dados relacionais do Java chamada JDBC, e tambm existem diversas ferramentas do tipo ORM (Object Relational Mapping) que facilitam bastante o uso do JDBC. Neste momento, focaremos nos conceitos e no uso do JDBC. Veremos um pouco da ferramenta de ORM Hibernate ao final deste mesmo curso e, no curso FJ-25, com muitos detalhes, recursos e tpicos avanados.

2.2 - PERSISTINDO ATRAVS DE SOCKETS?


Para conectar-se a um banco de dados poderamos abrir sockets diretamente com o servidor que o hospeda, por exemplo um Oracle ou

MySQL e nos comunicarmos com ele atravs de seu protocolo proprietrio. Mas voc conhece o protocolo proprietrio de algum banco de dados? Conhecer um protocolo complexo em profundidade difcil, trabalhar com ele muito trabalhoso. Uma segunda ideia seria utilizar uma API especfica para cada banco de dados. Antigamente, no PHP, por exemplo, a nica maneira de acessar o Oracle era atravs de funes como o r a c l e _ c o n n e c t , o r a c l e _ r e s u l t , e assim por diante. O MySQL tinha suas funes anlogas, como m y s q l _ c o n n e c t . Essa abordagem facilita muito nosso trabalho por no precisarmos entender o protocolo de cada banco, mas faz com que tenhamos de conhecer uma API um pouco diferente para cada tipo de banco. Alm disso, caso precisemos trocar de banco de dados um dia, precisaremos trocar todo o nosso cdigo para refletir a funo correta de acordo com o novo banco de dados que estamos utilizando.

Voc pode tambm fazer o curso FJ-21 dessa apostila na Caelum Querendo aprender ainda mais sobre Java na Web e Hibernate? Esclarecer dvidas dos exerccios? Ouvir explicaes detalhadas com um instrutor? A Caelum oferece o curso FJ-21 presencial nas cidades de So Paulo, Rio de Janeiro e Braslia, alm de turmas incompany. Consulte as vantagens do curso Java para Desenvolvimento Web.

2.3 - A CONEXO EM JAVA


Conectar-se a um banco de dados com Java feito de maneira elegante. Para evitar que cada banco tenha a sua prpria API e conjunto de classes e mtodos, temos um nico conjunto de interfaces muito bem definidas que devem ser implementadas. Esse conjunto de interfaces fica dentro do pacote j a v a . s q le nos referiremos a ela como JDBC.

Entre as diversas interfaces deste pacote, existe a interface C o n n e c t i o nque define mtodos para executar uma query (como um i n s e r te s e l e c t ), comitar transao e fechar a conexo, entre outros. Caso queiramos trabalhar com o MySQL, precisamos de classes concretas que implementem essas interfaces do pacote j a v a . s q l . Esse conjunto de classes concretas quem far a ponte entre o cdigo cliente que usa a API JDBC e o banco de dados. So essas classes que sabem se comunicar atravs do protocolo proprietrio do banco de dados. Esse conjunto de classes recebe o nome de driver. Todos os principais bancos de dados do mercado possuem drivers JDBC para que voc possa utiliz-los com Java. O nome driver anlogo ao que usamos para impressoras: como impossvel que um sistema operacional saiba conversar com todo tipo de impressora existente, precisamos de um driver que faa o papel de "tradutor" dessa conversa.

Para abrir uma conexo com um banco de dados, precisamos utilizar sempre um driver. A classe D r i v e r M a n a g e r a responsvel por se comunicar com todos os drivers que voc deixou disponvel. Para isso, invocamos o mtodo esttico g e t C o n n e c t i o ncom uma S t r i n gque indica a qual banco desejamos nos conectar. Essa S t r i n g- chamada de String de conexo JDBC - que utilizaremos para acessar o MySQL tem sempre a seguinte forma:
j d b c : m y s q l : / / i p / n o m e _ d o _ b a n c o

Devemos substituir i ppelo IP da mquina do servidor e n o m e _ d o _ b a n c opelo nome do banco de dados a ser utilizado. Seguindo o exemplo da linha acima e tudo que foi dito at agora, seria possvel rodar o exemplo abaixo e receber uma conexo para um banco MySQL, caso ele esteja rodando na mesma mquina:
p u b l i cc l a s sJ D B C E x e m p l o{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s )t h r o w sS Q L E x c e p t i o n{ C o n n e c t i o nc o n e x a o=D r i v e r M a n a g e r . g e t C o n n e c t i o n ( " j d b c : m y s q l : / / l o c a l h o s t / f j 2 1 " ) ; S y s t e m . o u t . p r i n t l n ( " C o n e c t a d o ! " ) ; c o n e x a o . c l o s e ( ) ; } }

Repare que estamos deixando passar a S Q L E x c e p t i o n , que uma

exception checked, lanada por muitos dos mtodos da API de JDBC. Numa aplicao real devemos utilizar t r y / c a t c hnos lugares que julgamos haver possibilidade de recuperar de uma falha com o banco de dados. Tambm precisamos tomar sempre cuidado para fechar todas as conexes que foram abertas. Ao testar o cdigo acima, recebemos uma exception. A conexo no pde ser aberta. Recebemos a mensagem:
j a v a . s q l . S Q L E x c e p t i o n :N os u i t a b l ed r i v e rf o u n df o r j d b c : m y s q l : / / l o c a l h o s t / f j 2 1

Por que? O sistema ainda no achou uma implementao de driver JDBC que pode ser usada para abrir a conexo indicada pela URL j d b c : m y s q l : / / l o c a l h o s t / f j 2 1 . O que precisamos fazer adicionar o driver do MySQL ao classpath, o arquivo .jar contendo a implementao JDBC do MySQL (mysql connector) precisa ser colocado em um lugar visvel pelo seu projeto ou adicionado varivel de ambiente C L A S S P A T H . Como usaremos o Eclipse, fazemos isso atravs de um clique da direita em nosso projeto, Properties/Java Build Path e em Libraries adicionamos o jar do driver JDBC do MySQL. Veremos isto passo a passo nos exerccios.

E o Class.forName ? At a verso 3 do JDBC, antes de chamar o D r i v e r M a n a g e r . g e t C o n n e c t i o n ( )era necessrio registrar o driver JDBC que iria ser utilizado atravs do mtodo C l a s s . f o r N a m e ( " c o m . m y s q l . j d b c . D r i v e r " ) , no caso do

MySQL, que carregava essa classe, e essa se comunicava com o D r i v e r M a n a g e r . A partir do JDBC 4, que est presente no Java 6, esse passo no mais necessrio. Mas lembre-se, caso voc utilize JDBC em um projeto com Java 5 ou anterior, ser preciso fazer o registro do Driver JDBC, carregando a sua classe, que vai se registrar no D r i v e r M a n a g e r .

Alterando o banco de dados Teoricamente, basta alterar as duas S t r i n g sque escrevemos para mudar de um banco para outro. Porm, no tudo to simples assim! O cdigo S Q Lque veremos a seguir pode funcionar em um banco e no em outros. Depende de quo aderente ao padro A N S IS Q L seu banco de dados. Isso s causa dor de cabea e existem projetos que resolvem isso, como o caso do Hibernate (www.hibernate.org) e da especificao JPA (Java Persistence API). Veremos um pouco do Hibernate ao final desse curso e bastante sobre ele no FJ-25.

Lista de drivers Os drivers podem ser baixados normalmente no site do fabricante do banco de dados. Alguns casos, como no Microsoft SQL Server, existem outros grupos que desenvolvem o driver em http://jtds.sourceforge.net

. Enquanto isso, voc pode achar o driver do MYSQL (chamado de mysql connector) no site http://www.mysql.org.

2.4 - FBRICA DE CONEXES


Em determinado momento de nossa aplicao, gostaramos de ter o controle sobre a construo dos objetos da nossa classe. Muito pode ser feito atravs do construtor, como saber quantos objetos foram instanciados ou fazer o log sobre essas instanciaes. s vezes, tambm queremos controlar um processo muito repetitivo e trabalhoso, como abrir uma conexo com o banco de dados. Tomemos como exemplo a classe a seguir que seria responsvel por abrir uma conexo com o banco:
p u b l i cc l a s sC o n n e c t i o n F a c t o r y{ p u b l i cC o n n e c t i o ng e t C o n n e c t i o n ( ){ t r y{ r e t u r nD r i v e r M a n a g e r . g e t C o n n e c t i o n ( " j d b c : m y s q l : / / l o c a l h o s t / f j 2 1 " ," r o o t " ," " ) ; }c a t c h( S Q L E x c e p t i o ne ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; } } }

Poderamos colocar um aviso na nossa aplicao, notificando todos os programadores a adquirir uma conexo:
C o n n e c t i o nc o n=n e wC o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ;

Note que o mtodo g e t C o n n e c t i o n ( ) uma fbrica de conexes, isto , ele cria novas conexes para ns. Basta invocar o mtodo e

recebemos uma conexo pronta para uso, no importando de onde elas vieram e eventuais detalhes de criao. Portanto, vamos chamar a classe de C o n n e c t i o n F a c t o r ye o mtodo de g e t C o n n e c t i o n . Encapsulando dessa forma, podemos mais tarde mudar a obteno de conexes, para, por exemplo, usar um mecanismo de pooling, que fortemente recomendvel em uma aplicao real.

Tratamento de Excees Repare que estamos fazendo um t r y / c a t c hem S Q L E x c e p t i o ne relanando-a como uma R u n t i m e E x c e p t i o n . Fazemos isso para que o seu cdigo que chamar a fbrica de conexes no fique acoplado com a API de JDBC. Toda vez que tivermos que lidar com uma S Q L E x c e p t i o n , vamos relan-las como R u n t i m e E x c e p t i o n . Poderamos ainda criar nossa prpria exceo que indicaria que ocorreu um erro dentro da nossa Factory, algo como uma C o n n e c t i o n F a c t o r y E x c e p t i o n .

2.5 - DESIGN PATTERNS


Orientao a objetos resolve as grandes dores de cabea que tnhamos na programao procedural, restringindo e centralizando responsabilidades. Mas alguns problemas no podemos simplesmente resolver com orientao a objetos, pois no existe palavra chave para uma

funcionalidade to especfica. Alguns desses pequenos problemas aparecem com tanta frequncia que as pessoas desenvolvem uma soluo "padro" para ele. Com isso, ao nos defrontarmos com um desses problemas clssicos, podemos rapidamente implementar essa soluo genrica com uma ou outra modificao, de acordo com nossa necessidade. Essa soluo padro tem o nome de Design Pattern (Padro de Projeto). A melhor maneira para aprender o que um Design Pattern vendo como surgiu sua necessidade. A nossa C o n n e c t i o n F a c t o r yimplementa o design pattern F a c t o r y que prega o encapsulamento da construo (fabricao) de objetos complicados.

A bblia dos Design Patterns O livro mais conhecido de Design Patterns foi escrito em 1995 e tem trechos de cdigo em C++ e Smalltalk. Mas o que realmente importa so os conceitos e os diagramas que fazem desse livro independente de qualquer linguagem. Alm de tudo, o livro de leitura agradvel. Design Patterns, Erich Gamma et al.

Tire suas dvidas no novo GUJ Respostas O GUJ um dos principais fruns brasileiros de computao e o maior em portugus sobre Java. A nova verso do GUJ baseada

em uma ferramenta de perguntas e respostas (QA) e tem uma comunidade muito forte. So mais de 150 mil usurios pra ajudar voc a esclarecer suas dvidas. Faa sua pergunta.

2.6 - EXERCCIOS: CONNECTIONFACTORY


1. Nos computadores da Caelum, clique no cone do Eclipse no Desktop;

Baixando o Eclipse em casa Estamos usando o Eclipse for Java EE Developers. Voc pode obt-lo direto no site do Eclipse em www.eclipse.org

a. Feche a tela de Welcome caso ela aparea b. Vamos criar um projeto no Eclipse chamado f j 2 1 j d b c . c. V em File -> New -> Project:

d. Selecione Java Project e clique em Next:

e. Coloque o nome do projeto como fj21-jdbc e clique em Finish:

f. Aceite a mudana de perspectiva:

2. Copie o driver do M y S Q Lpara o seu projeto. a. no seu Desktop, clique na pasta Caelum/21; b. clique da direita no driver do MySQL mais novo, escolha Copy;

c. v para sua pasta principal (webXXX) na coluna da direita do File Browser; d. entre no diretrio workspace, f j 2 1 j d b c ; e. clique da direita e escolha Paste: voc acaba de colocar o arquivo ".jar" no seu projeto. 3. Vamos criar a classe que fabrica conexes: a. Clique em File -> New -> Class. b. Crie-a no pacote b r . c o m . c a e l u m . j d b ce nomeie-a como
C o n n e c t i o n F a c t o r y .

c. Clique em Finish d. No cdigo, crie o mtodo g e t C o n n e c t i o nque retorna uma nova conexo. Quando perguntado, importe as classes do pacote j a v a . s q l (cuidado para no importar NADA de c o m . m y s q l ).
1 2 3 4 5 6 7 8

p u b l i cC o n n e c t i o ng e t C o n n e c t i o n ( ){ t r y{ r e t u r nD r i v e r M a n a g e r . g e t C o n n e c t i o n ( " j d b c : m y s q l : / / l o c a l h o s t / f j 2 1 " ," r o o t " ," " ) ; }c a t c h( S Q L E x c e p t i o ne ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; } }

4. Crie uma classe chamada T e s t a C o n e x a ono pacote b r . c o m . c a e l u m . j d b c . t e s t e . Todas as nossas classes de teste devero ficar nesse pacote. a. Crie um mtodo m a i ndentro da classe. Use o atalho do Eclipse para ajudar. b. Dentro do m a i n , fabrique uma conexo usando a C o n n e c t i o n F a c t o r y que criamos. Vamos apenas testar a abertura da conexo e depois fech-la com o mtodo c l o s e :
C o n n e c t i o nc o n n e c t i o n=n e w C o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; S y s t e m . o u t . p r i n t l n ( " C o n e x oa b e r t a ! " ) ; c o n n e c t i o n . c l o s e ( ) ;

c. Trate os erros com throws. ( Use: Ctrl + 1 e escolha "a d dt h r o w s


d e c l a r a t i o n ").

5. Rode a sua classe T e s t a C o n e x a opelo Eclipse. a. Clique da direita na sua classe T e s t a C o n e x a o b. Escolha Run as, Java Application (caso prefira, aprenda a tecla de atalho para agilizar nas prximas execues)

6. Parece que a aplicao no funciona pois o driver no foi encontrado? Esquecemos de colocar o JAR no classpath! (Build Path no Eclipse) a. Clique no seu projeto com o boto da direita e escolha Refresh (ou pressione F5). b. Selecione o seu driver do MySQL, clique da direita e escolha Build Path, Add to Build Path:

c. Rode novamente sua aplicao T e s t a C o n e x a oagora que colocamos o driver no classpath.

2.7 - A TABELA CONTATO


Para criar uma tabela nova, primeiro devemos acessar o terminal e fazermos o comando para logarmos no mysql.
m y s q lur o o t

Nos preparamos para usar o banco de dados fj21:


u s ef j 2 1 ;

A seguinte tabela ser usada nos exemplos desse captulo:

c r e a t et a b l ec o n t a t o s( i dB I G I N TN O TN U L LA U T O _ I N C R E M E N T , n o m eV A R C H A R ( 2 5 5 ) , e m a i lV A R C H A R ( 2 5 5 ) , e n d e r e c oV A R C H A R ( 2 5 5 ) , d a t a N a s c i m e n t oD A T E , p r i m a r yk e y( i d ) ) ;

No banco de dados relacional, comum representar um contato (entidade) em uma tabela de contatos.

2.8 - JAVABEANS
O que so Javabeans? A pergunta que no quer se calar pode ser respondida muito facilmente uma vez que a uma das maiores confuses feitas a fora entre Javabeans e Enterprise Java Beans (EJB). Javabeans so classes que possuem o construtor sem argumentos e mtodos de acesso do tipo g e te s e t ! Mais nada! Simples, no? J os EJBs costumam ser javabeans com caractersticas mais avanadas e so o assunto principal do curso FJ-31 da Caelum. Podemos usar beans por diversos motivos, normalmente as classes de modelo da nossa aplicao costumam ser javabeans. Utilizaremos: uma classe com mtodos do tipo g e te s e tpara cada um de seus parmetros, que representa algum objeto; uma classe com construtor sem argumentos que representa uma coleo de objetos.

A seguir, voc v um exemplo de uma classe JavaBean que seria equivalente ao nosso modelo de entidade do banco de dados:
p a c k a g eb r . c o m . c a e l u m . j d b c . m o d e l o ; p u b l i cc l a s sC o n t a t o{ p r i v a t eL o n gi d ; p r i v a t eS t r i n gn o m e ; p r i v a t eS t r i n ge m a i l ; p r i v a t eS t r i n ge n d e r e c o ; p r i v a t eC a l e n d a rd a t a N a s c i m e n t o ; / /m t o d o sg e tes e tp a r ai d ,n o m e ,e m a i l ,e n d e r e oe d a t a N a s c i m e n t o p u b l i cS t r i n gg e t N o m e ( ){ r e t u r nt h i s . n o m e ; } p u b l i cv o i ds e t N o m e ( S t r i n gn o v o ){ t h i s . n o m e=n o v o ; } p u b l i cS t r i n gg e t E m a i l ( ){ r e t u r nt h i s . e m a i l ; } p u b l i cv o i ds e t E m a i l ( S t r i n gn o v o ){ t h i s . e m a i l=n o v o ; } p u b l i cS t r i n gg e t E n d e r e c o ( ){ r e t u r nt h i s . e n d e r e c o ; } p u b l i cv o i ds e t E n d e r e c o ( S t r i n gn o v o ){ t h i s . e n d e r e c o=n o v o ; } p u b l i cL o n gg e t I d ( ){ r e t u r nt h i s . i d ; } p u b l i cv o i ds e t I d ( L o n gn o v o ){ t h i s . i d=n o v o ;

} p u b l i cC a l e n d a rg e t D a t a N a s c i m e n t o ( ){ r e t u r nt h i s . d a t a N a s c i m e n t o ; } p u b l i cv o i ds e t D a t a N a s c i m e n t o ( C a l e n d a rd a t a N a s c i m e n t o ){ t h i s . d a t a N a s c i m e n t o=d a t a N a s c i m e n t o ; } }

A especificao JavaBeans muito grande e mais informaes sobre essa vasta rea que a base dos componentes escritos em Java pode ser encontrada em: http://java.sun.com/products/javabeans

Mtodos getters e setters Um erro muito comum cometido pelos desenvolvedores Java a criao dos mtodos getters e setters indiscriminadamente, sem ter a real necessidade da existncia tais mtodos. Existe um artigo no blog da caelum que trata desse assunto: http://blog.caelum.com.br/2006/09/14/nao-aprender-oogetters-e-setters/ Os cursos FJ-11 e FJ-22 tambm mostram isso claramente quando criam algumas entidades que no possuem apenas getters e setters.

Se voc quer saber mais sobre Enterprise Java Beans (EJB), a Caelum oferece o curso FJ-31. No os confunda com Java Beans!

Nova editora Casa do Cdigo com livros de uma forma diferente Editoras tradicionais pouco ligam para ebooks e novas tecnologias. No conhecem programao para revisar os livros tecnicamente a fundo. No tm anos de experincia em didticas com cursos. Conhea a Casa do Cdigo, uma editora diferente, com curadoria da Caelum e obsesso por livros de qualidade a preos justos. Casa do Cdigo, ebook com preo de ebook.

2.9 - INSERINDO DADOS NO BANCO


Para inserir dados em uma tabela de um banco de dados entidaderelacional basta usar a clusula INSERT. Precisamos especificar quais os campos que desejamos atualizar e os valores. Primeiro o cdigo SQL:
S t r i n gs q l=" i n s e r ti n t oc o n t a t o s"+ " ( n o m e , e m a i l , e n d e r e c o ,d a t a N a s c i m e n t o ) "+ "v a l u e s( ' "+n o m e+" ' ,' "+e m a i l+" ' ,' "+ e n d e r e c o+" ' ,' " +d a t a N a s c i m e n t o+ " ' ) " ;

O exemplo acima possui trs pontos negativos que so importantssimos. O primeiro que o programador que no escreveu o cdigo original no consegue bater o olho e entender o que est escrito. O que o cdigo acima faz? Lendo rapidamente fica difcil. Mais difcil ainda saber se faltou uma vrgula, um fecha parnteses talvez? E ainda assim, esse um caso simples. Existem tabelas com 10, 20, 30 e

at mais campos, tornando invivel entender o que est escrito no SQL misturado com as concatenaes. Outro problema o clssico "preconceito contra Joana D'arc", formalmente chamado de SQL Injection. O que acontece quando o contato a ser adicionado possui no nome uma aspas simples? O cdigo SQL se quebra todo e para de funcionar ou, pior ainda, o usurio final capaz de alterar seu cdigo sql para executar aquilo que ele deseja (SQL injection)... tudo isso porque escolhemos aquela linha de cdigo e no fizemos o escape de caracteres especiais. Mais um problema que enxergamos a na data. Ela precisa ser passada no formato que o banco de dados entenda e como uma S t r i n g , portanto, se voc possui um objeto j a v a . u t i l . C a l e n d a rque o nosso caso, voc precisar fazer a converso desse objeto para a String. Por esses trs motivos no usaremos cdigo SQL como mostrado anteriormente. Vamos imaginar algo mais genrico e um pouco mais interessante:
S t r i n gs q l=" i n s e r ti n t oc o n t a t o s"+ " ( n o m e , e m a i l , e n d e r e c o , d a t a N a s c i m e n t o )"+ " v a l u e s( ? , ? , ? , ? ) " ;

Existe uma maneira em Java de escrever o cdigo SQL como no primeiro exemplo dessa seo (com concatenaes de strings). Essa maneira no ser ensinada durante o curso pois uma pssima prtica que dificulta a manuteno do seu projeto. Perceba que no colocamos os pontos de interrogao de brincadeira, mas sim porque realmente no sabemos o que desejamos inserir. Estamos interessados em executar aquele cdigo mas no sabemos ainda quais so os parmetros que utilizaremos nesse cdigo SQL que

ser executado, chamado de s t a t e m e n t . As clusulas so executadas em um banco de dados atravs da interface P r e p a r e d S t a t e m e n t . Para receber um P r e p a r e d S t a t e m e n t relativo conexo, basta chamar o mtodo p r e p a r e S t a t e m e n t , passando como argumento o comando SQL com os valores vindos de variveis preenchidos com uma interrogao.
S t r i n gs q l=" i n s e r ti n t oc o n t a t o s"+ " ( n o m e , e m a i l , e n d e r e c o , d a t a N a s c i m e n t o )"+ " v a l u e s( ? , ? , ? , ? ) " ; P r e p a r e d S t a t e m e n ts t m t=c o n n e c t i o n . p r e p a r e S t a t e m e n t ( s q l ) ;

Logo em seguida, chamamos o mtodo s e t S t r i n gdo P r e p a r e d S t a t e m e n tpara preencher os valores que so do tipo S t r i n g , passando a posio (comeando em 1) da interrogao no SQL e o valor que deve ser colocado:
/ /p r e e n c h eo sv a l o r e s s t m t . s e t S t r i n g ( 1 ," C a e l u m " ) ; s t m t . s e t S t r i n g ( 2 ," c o n t a t o @ c a e l u m . c o m . b r " ) ; s t m t . s e t S t r i n g ( 3 ," R .V e r g u e i r o3 1 8 5c j 5 7 " ) ;

Precisamos definir tambm a data de nascimento do nosso contato, para isso, precisaremos de um objeto do tipo j a v a . s q l . D a t epara passarmos para o nosso P r e p a r e d S t a t e m e n t . Nesse exemplo, vamos passar a data atual. Para isso, vamos passar um l o n gque representa os milissegundos da data atual para dentro de um j a v a . s q l . D a t eque o tipo suportado pela API JDBC. Vamos utilizar a classe C a l e n d a rpara conseguirmos esses milissegundos:
j a v a . s q l . D a t ed a t a P a r a G r a v a r=n e wj a v a . s q l . D a t e ( C a l e n d a r . g e t I n s t a n c e ( ) . g e t T i m e I n M i l l i s ( ) ) ; s t m t . s e t D a t e ( 4 ,d a t a P a r a G r a v a r ) ;

Por fim, uma chamada a e x e c u t e ( )executa o comando SQL:

s t m t . e x e c u t e ( ) ;

Imagine todo esse processo sendo escrito toda vez que desejar inserir algo no banco? Ainda no consegue visualizar o quo destrutivo isso pode ser? Veja o exemplo abaixo, que abre uma conexo e insere um contato no banco:
p u b l i cc l a s sJ D B C I n s e r e{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s )t h r o w sS Q L E x c e p t i o n{ / /c o n e c t a n d o C o n n e c t i o nc o n=n e w C o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; / /c r i au mp r e p a r e d S t a t e m e n t S t r i n gs q l=" i n s e r ti n t oc o n t a t o s "+ "( n o m e , e m a i l , e n d e r e c o , d a t a N a s c i m e n t o ) "+ "v a l u e s( ? , ? , ? , ? ) " ; P r e p a r e d S t a t e m e n ts t m t=c o n . p r e p a r e S t a t e m e n t ( s q l ) ; / /p r e e n c h eo sv a l o r e s s t m t . s e t S t r i n g ( 1 ," C a e l u m " ) ; s t m t . s e t S t r i n g ( 2 ," c o n t a t o @ c a e l u m . c o m . b r " ) ; s t m t . s e t S t r i n g ( 3 ," R .V e r g u e i r o3 1 8 5c j 5 7 " ) ; s t m t . s e t D a t e ( 4 ,n e wj a v a . s q l . D a t e ( C a l e n d a r . g e t I n s t a n c e ( ) . g e t T i m e I n M i l l i s ( ) ) ) ; / /e x e c u t a s t m t . e x e c u t e ( ) ; s t m t . c l o s e ( ) ; S y s t e m . o u t . p r i n t l n ( " G r a v a d o ! " ) ; c o n . c l o s e ( ) ; } }

Para saber mais: Fechando a conexo propriamente

No comum utilizar JDBC diretamente hoje em dia. O mais praticado o uso de alguma API de ORM como a JPA ou o Hibernate. Tanto na JDBC quanto em bibliotecas ORM deve-se prestar ateno no momento de fechar a conexo. O exemplo dado acima no a fecha caso algum erro ocorra no momento de inserir um dado no banco de dados. O comum fechar a conexo em um bloco f i n a l l y :
p u b l i cc l a s sJ D B C I n s e r e{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s )t h r o w sS Q L E x c e p t i o n { C o n n e c t i o nc o n=n u l l ; t r y{ c o n=n e wC o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; / /f a zu mm o n t ed eo p e r a e s . / /q u ep o d e ml a n a re x c e p t i o n sr u n t i m eeS Q L E x c e p t i o n c a t c h ( S Q L E x c e p t i o ne ){ S y s t e m . o u t . p r i n t l n ( e ) ; }f i n a l l y{ c o n . c l o s e ( ) ; } } }

Dessa forma, mesmo que o cdigo dentro do t r ylance exception, o c o n . c l o s e ( )ser executado. Garantimos que no deixaremos uma conexo pendurada sem uso. Esse cdigo pode ficar muito maior se quisermos ir alm. Pois o que acontece no caso de c o n . c l o s elanar uma exception? Quem a tratar? Trabalhar com recursos caros, como conexes, sesses, threads e arquivos, sempre deve ser muito bem pensado. Deve-se tomar cuidado para no deixar nenhum desses recursos abertos, pois poder vazar algo precioso da nossa aplicao. Como veremos durante o curso,

importante centralizar esse tipo de cdigo em algum lugar, para no repetir uma tarefa complicada como essa. Alm disso, h a estrutura do Java 7 conhecida como try-withresources. Ela permite declarar e inicializar, dentro do t r y , objetos que implementam A u t o C l o s e a b l e . Dessa forma, ao trmino do t r y ,o prprio compilador inserir instrues para invocar o c l o s edesses recursos, alm de se precaver em relao a excees que podem surgir por causa dessa invocao. Nosso cdigo ficaria mais reduzido e organizado, alm do escopo de c o ns valer dentro do t r y :
t r y ( C o n n e c t i o nc o n=n e wC o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ){ / /f a zu mm o n t ed eo p e r a e s . / /q u ep o d e ml a n a re x c e p t i o n sr u n t i m eeS Q L E x c e p t i o n }c a t c h ( S Q L E x c e p t i o ne ){ S y s t e m . o u t . p r i n t l n ( e ) ; }

Para saber mais: A m prtica Statement


Em vez de usar o P r e p a r e d S t a t e m e n t , voc pode usar uma interface mais simples chamada S t a t e m e n t , que simplesmente executa uma clusula SQL no mtodo e x e c u t e :
S t a t e m e n ts t m t=c o n . c r e a t e S t a t e m e n t ( ) ; s t m t . e x e c u t e ( " I N S E R TI N T O. . . " ) ; s t m t . c l o s e ( ) ;

Mas prefira a classe P r e p a r e d S t a t e m e n tque mais rpida que S t a t e m e n te deixa seu cdigo muito mais limpo. Geralmente, seus comandos SQL contero valores vindos de variveis do programa Java; usando S t a t e m e n t s , voc ter que fazer muitas concatenaes, mas usando P r e p a r e d S t a t e m e n t s , isso fica mais limpo e fcil.

Para saber mais: JodaTime


A API de datas do Java, mesmo considerando algumas melhorias da
C a l e n d a rem relao

aD a t e , ainda muito pobre. Na verso 8 do Java

entra novas classes para facilitar o trabalho com datas e horrios, baseado na excelente biblioteca JodaTime. Para mais informaes: http://blog.caelum.com.br/2007/03/15/jsr310-date-and-time-api/http://jcp.org/en/jsr/detail?id=310

2.10 - DAO - DATA ACCESS OBJECT


J foi possvel sentir que colocar cdigo SQL dentro de suas classes de lgica algo nem um pouco elegante e muito menos vivel quando voc precisa manter o seu cdigo. Quantas vezes voc no ficou bravo com o programador responsvel por aquele cdigo ilegvel? A ideia a seguir remover o cdigo de acesso ao banco de dados de suas classes de lgica e coloc-lo em uma classe responsvel pelo acesso aos dados. Assim o cdigo de acesso ao banco de dados fica em um lugar s, tornando mais fcil a manuteno. Que tal se pudssemos chamar um mtodo adiciona que adiciona um C o n t a t oao banco? Em outras palavras quero que o cdigo a seguir funcione:
/ /a d i c i o n ao sd a d o sn ob a n c o M i s t e r i ob d=n e wM i s t e r i o ( ) ; b d . a d i c i o n a ( " m e un o m e " ," m e ue m a i l " ," m e ue n d e r e o " , m e u C a l e n d a r ) ;

Tem algo estranho nesse cdigo. Repare que todos os parmetros que estamos passando so as informaes do contato. Se contato tivesse 20 atributos, passaramos 20 parmetros? Java orientado a S t r i n g s ? Vamos tentar novamente: em outras palavras quero que o cdigo a seguir funcione:
/ /a d i c i o n au mc o n t a t on ob a n c o M i s t e r i ob d=n e wM i s t e r i o ( ) ; / /m t o d om u i t om a i se l e g a n t e b d . a d i c i o n a ( c o n t a t o ) ;

Tentaremos chegar ao cdigo anterior: seria muito melhor e mais elegante poder chamar um nico mtodo responsvel pela incluso, certo?
p u b l i cc l a s sT e s t a I n s e r e{ p u b l i cs t a t i cv o i dm a i n ( S t r i n g [ ]a r g s ){ / /p r o n t op a r ag r a v a r C o n t a t oc o n t a t o=n e wC o n t a t o ( ) ; c o n t a t o . s e t N o m e ( " C a e l u m " ) ; c o n t a t o . s e t E m a i l ( " c o n t a t o @ c a e l u m . c o m . b r " ) ; c o n t a t o . s e t E n d e r e c o ( " R .V e r g u e i r o3 1 8 5c j 8 7 " ) ; c o n t a t o . s e t D a t a N a s c i m e n t o ( C a l e n d a r . g e t I n s t a n c e ( ) ) ; / /g r a v en e s s ac o n e x o ! ! ! M i s t e r i ob d=n e wM i s t e r i o ( ) ; / /m t o d oe l e g a n t e b d . a d i c i o n a ( c o n t a t o ) ; S y s t e m . o u t . p r i n t l n ( " G r a v a d o ! " ) ; } }

O cdigo anterior j mostra o poder que alcanaremos: atravs de uma nica classe seremos capazes de acessar o banco de dados e, mais

ainda, somente atravs dessa classe ser possvel acessar os dados. Esta ideia, inocente primeira vista, capaz de isolar todo o acesso a banco em classes bem simples, cuja instncia um objeto responsvel por acessar os dados. Da responsabilidade deste objeto surgiu o nome de Data Access Object ou simplesmente DAO, um dos mais famosos padres de projeto (design pattern). O que falta para o cdigo acima funcionar uma classe chamada C o n t a t o D a ocom um mtodo chamado a d i c i o n a . Vamos criar uma que se conecta ao banco ao construirmos uma instncia dela:
p u b l i cc l a s sC o n t a t o D a o{ / /ac o n e x oc o mob a n c od ed a d o s p r i v a t eC o n n e c t i o nc o n n e c t i o n ; p u b l i cC o n t a t o D a o ( ){ t h i s . c o n n e c t i o n=n e wC o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; } }

Agora que todo C o n t a t o D a opossui uma conexo com o banco, podemos focar no mtodo a d i c i o n a , que recebe um C o n t a t ocomo argumento e responsvel por adicion-lo atravs de cdigo SQL:
p u b l i cv o i da d i c i o n a ( C o n t a t oc o n t a t o ){ S t r i n gs q l=" i n s e r ti n t oc o n t a t o s"+ " ( n o m e , e m a i l , e n d e r e c o , d a t a N a s c i m e n t o ) "+ "v a l u e s( ? , ? , ? , ? ) " ; t r y{ / /p r e p a r e ds t a t e m e n tp a r ai n s e r o P r e p a r e d S t a t e m e n ts t m t=c o n . p r e p a r e S t a t e m e n t ( s q l ) ; / /s e t ao sv a l o r e s s t m t . s e t S t r i n g ( 1 , c o n t a t o . g e t N o m e ( ) ) ;

s t m t . s e t S t r i n g ( 2 , c o n t a t o . g e t E m a i l ( ) ) ; s t m t . s e t S t r i n g ( 3 , c o n t a t o . g e t E n d e r e c o ( ) ) ; s t m t . s e t D a t e ( 4 ,n e wD a t e ( c o n t a t o . g e t D a t a N a s c i m e n t o ( ) . g e t T i m e I n M i l l i s ( ) ) ) ; / /e x e c u t a s t m t . e x e c u t e ( ) ; s t m t . c l o s e ( ) ; }c a t c h( S Q L E x c e p t i o ne ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; } }

Encapsulamos a S Q L E x c e p t i o nem uma R u n t i m e E x c e p t i o n mantendo a ideia anterior da C o n n e c t i o n F a c t o r yde desacoplar o cdigo de API de JDBC.

2.11 - EXERCCIOS: JAVABEANS E CONTATODAO


1. Crie a classe de C o n t a t ono pacote b r . c o m . c a e l u m . j d b c . m o d e l o . Ela ser nosso JavaBean para representar a entidade do banco. Dever ter id, nome, email, endereo e uma data de nascimento. Coloque os atributos na classe e gere os getters e setters para cada atributo:
1 2 3 4 5 6 7

p u b l i cc l a s sC o n t a t o{ p r i v a t eL o n gi d ; p r i v a t eS t r i n gn o m e ; p r i v a t eS t r i n ge m a i l ; p r i v a t eS t r i n ge n d e r e c o ; p r i v a t eC a l e n d a rd a t a N a s c i m e n t o ; }

Dica: use o atalho do Eclipse para gerar os getters e setters. Aperte C t r l+3 , digite g g a sque a abreviao de G e n e r a t eg e t t e r sa n d

s e t t e r se selecione todos os getters e setters.

2. Vamos desenvolver nossa classe de DAO. Crie a classe C o n t a t o D a o no pacote b r . c o m . c a e l u m . j d b c . d a o . Seu papel ser gerenciar a conexo e inserir Contatos no banco de dados. Para a conexo, vamos cri-la no construtor e salvar em um atributo:
1 2 3 4 5 6

p u b l i cc l a s sC o n t a t o D a o{ / /ac o n e x oc o mob a n c od ed a d o s p r i v a t eC o n n e c t i o nc o n n e c t i o n ;

p u b l i cC o n t a t o D a o ( ){ 7 t h i s . c o n n e c t i o n=n e w C o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; 8 }

9 1 0

Use o Eclipse para ajudar com os imports! (atalho Ctrl + Shift + O) O prximo passo criar o mtodo de adio de contatos. Ele deve receber um objeto do tipo C o n t a t ocomo argumento e encapsular totalmente o trabalho com o banco de dados. Internamente, use um P r e p a r e d S t a t e m e n tcomo vimos na aula para executar o SQL:
1 2 3 4 5 6

p u b l i cv o i da d i c i o n a ( C o n t a t oc o n t a t o ){ S t r i n gs q l=" i n s e r ti n t oc o n t a t o s"+ " ( n o m e , e m a i l , e n d e r e c o , d a t a N a s c i m e n t o ) "+ "v a l u e s( ? , ? , ? , ? ) " ;

t r y{ 7 / /p r e p a r e ds t a t e m e n tp a r ai n s e r o 8 P r e p a r e d S t a t e m e n ts t m t= c o n n e c t i o n . p r e p a r e S t a t e m e n t ( s q l ) ;
9 1 0 1 1 1 2 1 3 1 4 1 5

/ /s e t ao sv a l o r e s s t m t . s e t S t r i n g ( 1 , c o n t a t o . g e t N o m e ( ) ) ; s t m t . s e t S t r i n g ( 2 , c o n t a t o . g e t E m a i l ( ) ) ; s t m t . s e t S t r i n g ( 3 , c o n t a t o . g e t E n d e r e c o ( ) ) ; s t m t . s e t D a t e ( 4 ,n e wD a t e (

c o n t a t o . g e t D a t a N a s c i m e n t o ( ) . g e t T i m e I n M i l l i s ( ) ) ) ;
1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3

/ /e x e c u t a s t m t . e x e c u t e ( ) ; s t m t . c l o s e ( ) ; }c a t c h( S Q L E x c e p t i o ne ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; } }

ATENO: Lembre-se de importar as classes de SQL do pacote j a v a . s q l , inclusive a classe Date! 3. Para testar nosso DAO, desenvolva uma classe de testes com o

mtodo m a i n . Por exemplo, uma chamada T e s t a I n s e r eno pacote b r . c o m . c a e l u m . j d b c . t e s t e . Gere o m a i npelo Eclipse. O nosso programa de testes deve, dentro do m a i n , criar um novo objeto C o n t a t ocom dados de teste e chamar a nova classe C o n t a t o D a opara adicion-lo ao banco de dados:
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4

/ /p r o n t op a r ag r a v a r C o n t a t oc o n t a t o=n e wC o n t a t o ( ) ; c o n t a t o . s e t N o m e ( " C a e l u m " ) ; c o n t a t o . s e t E m a i l ( " c o n t a t o @ c a e l u m . c o m . b r " ) ; c o n t a t o . s e t E n d e r e c o ( " R .V e r g u e i r o3 1 8 5c j 5 7 " ) ; c o n t a t o . s e t D a t a N a s c i m e n t o ( C a l e n d a r . g e t I n s t a n c e ( ) ) ; / /g r a v en e s s ac o n e x o ! ! ! C o n t a t o D a od a o=n e wC o n t a t o D a o ( ) ; / /m t o d oe l e g a n t e d a o . a d i c i o n a ( c o n t a t o ) ; S y s t e m . o u t . p r i n t l n ( " G r a v a d o ! " ) ;

Execute seu programa e veja se tudo correu bem. 4. Verifique se o contato foi adicionado. Abra o terminal e digite:
m y s q lur o o t u s ef j 2 1 ; s e l e c t*f r o mc o n t a t o s ;

e x i tpara sair do console do MySQL.

J conhece os cursos online Alura? A Alura oferece dezenas de cursos online em sua plataforma exclusiva de ensino que favorece o aprendizado com a qualidade reconhecida da Caelum. Voc pode escolher um curso nas reas

de Java, Ruby, Web, Mobile, .NET e outros, com uma assinatura que d acesso a todos os cursos. Conhea os cursos online Alura.

2.12 - FAZENDO PESQUISAS NO BANCO DE DADOS


Para pesquisar tambm utilizamos a interface P r e p a r e d S t a t e m e n t para montar nosso comando SQL. Mas como uma pesquisa possui um retorno (diferente de uma simples insero), usaremos o mtodo e x e c u t e Q u e r yque retorna todos os registros de uma determinada query. O objeto retornado do tipo R e s u l t S e tdo JDBC, o que nos permite navegar por seus registros atravs do mtodo n e x t . Esse mtodo retornar f a l s equando chegar ao fim da pesquisa, portanto ele normalmente utilizado para fazer um lao nos registros:
/ /p e g aac o n e x oeoS t a t e m e n t C o n n e c t i o nc o n=n e wC o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; P r e p a r e d S t a t e m e n ts t m t=c o n . p r e p a r e S t a t e m e n t ( " s e l e c t*f r o m c o n t a t o s " ) ; / /e x e c u t au ms e l e c t R e s u l t S e tr s=s t m t . e x e c u t e Q u e r y ( ) ; / /i t e r an oR e s u l t S e t w h i l e( r s . n e x t ( ) ){ } r s . c l o s e ( ) ; s t m t . c l o s e ( ) ; c o n . c l o s e ( ) ;

Para retornar o valor de uma coluna no banco de dados, basta chamar

um dos mtodos g e tdo R e s u l t S e t , dentre os quais, o mais comum: g e t S t r i n g .


/ /p e g aac o n e x oeoS t a t e m e n t C o n n e c t i o nc o n=n e wC o n n e c t i o n F a c t o r y ( ) . g e t C o n n e c t i o n ( ) ; P r e p a r e d S t a t e m e n ts t m t=c o n . p r e p a r e S t a t e m e n t ( " s e l e c t*f r o m c o n t a t o s " ) ; / /e x e c u t au ms e l e c t R e s u l t S e tr s=s t m t . e x e c u t e Q u e r y ( ) ; / /i t e r an oR e s u l t S e t w h i l e( r s . n e x t ( ) ){ S t r i n gn o m e=r s . g e t S t r i n g ( " n o m e " ) ; S t r i n ge m a i l=r s . g e t S t r i n g ( " e m a i l " ) S y s t e m . o u t . p r i n t l n ( n o m e+": :"+e m a i l ) ; } s t m t . c l o s e ( ) ; c o n . c l o s e ( ) ;

Recurso Avanado: O cursor Assim como o cursor do banco de dados, s possvel mover para o prximo registro. Para permitir um processo de leitura para trs necessrio especificar na abertura do R e s u l t S e tque tal cursor deve ser utilizado.

Mas, novamente, podemos aplicar as ideias de DAO e criar um mtodo g e t L i s t a ( )no nosso C o n t a t o D a o . Mas o que esse mtodo retornaria? Um R e s u l t S e t ? E teramos o cdigo de manipulao de R e s u l t S e tespalhado por todo o cdigo? Vamos fazer nosso g e t L i s t a ( )devolver algo mais interessante, uma lista de C o n t a t o :

P r e p a r e d S t a t e m e n ts t m t=t h i s . c o n n e c t i o n . p r e p a r e S t a t e m e n t ( " s e l e c t*f r o mc o n t a t o s " ) ; R e s u l t S e tr s=s t m t . e x e c u t e Q u e r y ( ) ; L i s t < C o n t a t o >c o n t a t o s=n e wA r r a y L i s t < C o n t a t o > ( ) ; w h i l e( r s . n e x t ( ) ){ / /c r i a n d ooo b j e t oC o n t a t o C o n t a t oc o n t a t o=n e wC o n t a t o ( ) ; c o n t a t o . s e t N o m e ( r s . g e t S t r i n g ( " n o m e " ) ) ; c o n t a t o . s e t E m a i l ( r s . g e t S t r i n g ( " e m a i l " ) ) ; c o n t a t o . s e t E n d e r e c o ( r s . g e t S t r i n g ( " e n d e r e c o " ) ) ; / /m o n t a n d oad a t aa t r a v sd oC a l e n d a r C a l e n d a rd a t a=C a l e n d a r . g e t I n s t a n c e ( ) ; d a t a . s e t T i m e ( r s . g e t D a t e ( " d a t a N a s c i m e n t o " ) ) ; c o n t a t o . s e t D a t a N a s c i m e n t o ( d a t a ) ; / /a d i c i o n a n d ooo b j e t ol i s t a c o n t a t o s . a d d ( c o n t a t o ) ; } r s . c l o s e ( ) ; s t m t . c l o s e ( ) ; r e t u r nc o n t a t o s ;

2.13 - EXERCCIOS: LISTAGEM


1. Crie o mtodo g e t L i s t ana classe C o n t a t o D a o . Importe L i s tde j a v a . u t i l :
1 2 3 4 5 6 7

p u b l i cL i s t < C o n t a t o >g e t L i s t a ( ){ t r y{ L i s t < C o n t a t o >c o n t a t o s=n e wA r r a y L i s t < C o n t a t o > ( ) ; P r e p a r e d S t a t e m e n ts t m t=t h i s . c o n n e c t i o n . p r e p a r e S t a t e m e n t ( " s e l e c t*f r o mc o n t a t o s " ) ; R e s u l t S e tr s=s t m t . e x e c u t e Q u e r y ( ) ;

8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0

w h i l e( r s . n e x t ( ) ){ / /c r i a n d ooo b j e t oC o n t a t o C o n t a t oc o n t a t o=n e wC o n t a t o ( ) ; c o n t a t o . s e t I d ( r s . g e t L o n g ( " i d " ) ) ; c o n t a t o . s e t N o m e ( r s . g e t S t r i n g ( " n o m e " ) ) ; c o n t a t o . s e t E m a i l ( r s . g e t S t r i n g ( " e m a i l " ) ) ; c o n t a t o . s e t E n d e r e c o ( r s . g e t S t r i n g ( " e n d e r e c o " ) ) ; / /m o n t a n d oad a t aa t r a v sd oC a l e n d a r C a l e n d a rd a t a=C a l e n d a r . g e t I n s t a n c e ( ) ; d a t a . s e t T i m e ( r s . g e t D a t e ( " d a t a N a s c i m e n t o " ) ) ; c o n t a t o . s e t D a t a N a s c i m e n t o ( d a t a ) ; / /a d i c i o n a n d ooo b j e t ol i s t a c o n t a t o s . a d d ( c o n t a t o ) ; } r s . c l o s e ( ) ; s t m t . c l o s e ( ) ; r e t u r nc o n t a t o s ; }c a t c h( S Q L E x c e p t i o ne ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; } }

2. Vamos usar o mtodo g e t L i s t apara listar todos os contatos do nosso banco de dados. Crie uma classe chamada T e s t a L i s t acom um mtodo m a i n : a. Crie um ContatoDao:
C o n t a t o D a od a o=n e wC o n t a t o D a o ( ) ;

b. Liste os contatos com o DAO:


L i s t < C o n t a t o >c o n t a t o s=d a o . g e t L i s t a ( ) ;

c. Itere nessa lista e imprima as informaes dos contatos:


f o r( C o n t a t oc o n t a t o:c o n t a t o s ){ S y s t e m . o u t . p r i n t l n ( " N o m e :"+c o n t a t o . g e t N o m e ( ) ) ; S y s t e m . o u t . p r i n t l n ( " E m a i l :"+c o n t a t o . g e t E m a i l ( ) ) ;

S y s t e m . o u t . p r i n t l n ( " E n d e r e o :"+c o n t a t o . g e t E n d e r e c o ( ) ) ; S y s t e m . o u t . p r i n t l n ( " D a t ad eN a s c i m e n t o :"+ c o n t a t o . g e t D a t a N a s c i m e n t o ( ) . g e t T i m e ( )+" \ n " ) ; }

3. Rode o programa anterior clicando da direita no mesmo, Run, Run as Java Application (aproveite para aprender a tecla de atalho para executar a aplicao).

2.14 - UM POUCO MAIS...


1. Assim como o MySQL existem outros bancos de dados gratuitos e opensource na internet. O HSQLDB um banco desenvolvido em Java que pode ser acoplado a qualquer aplicao e libera o cliente da necessidade de baixar qualquer banco de dados antes da instalao de um produto Java! 2. O Hibernate tomou conta do mercado e virou febre mundial pois no se faz necessrio escrever uma linha de cdigo SQL! 3. Se um projeto no usa nenhuma das tecnologias de ORM (Object Relational Mapping) disponveis, o mnimo a ser feito seguir o DAO.

Voc no est nessa pgina a toa Voc chegou aqui porque a Caelum referncia nacional em cursos de Java, Ruby, Agile, Mobile, Web e .NET. Faa curso com quem escreveu essa apostila. Consulte as vantagens do curso Java para Desenvolvimento Web.

2.15 - EXERCCIOS OPCIONAIS


1. A impresso da data de nascimento ficou um pouco estranha. Para format-la, pesquise sobre a classe S i m p l e D a t e F o r m a t . 2. Crie uma classe chamada DAOException que estenda de R u n t i m e E x c e p t i o ne utilize-a no seu C o n t a t o D a o . 3. Use clusulas w h e r epara refinar sua pesquisa no banco de dados. Por exemplo: w h e r en o m el i k e' C % ' 4. Crie o mtodo p e s q u i s a rque recebe um id (int) e retorna um objeto do tipo C o n t a t o .

Desafios
1. Faa conexes para outros tipos de banco de dados disponveis.

2.16 - OUTROS MTODOS PARA O SEU DAO


Agora que voc j sabe usar o P r e p a r e d S t a t e m e n tpara executar qualquer tipo de cdigo SQL e R e s u l t S e tpara receber os dados retornados da sua pesquisa fica simples, porm maante, escrever o cdigo de diferentes mtodos de uma classe tpica de DAO. Veja primeiro o mtodo a l t e r a , que recebe um c o n t a t ocujos valores devem ser alterados:
p u b l i cv o i da l t e r a ( C o n t a t oc o n t a t o ){ 2 S t r i n gs q l=" u p d a t ec o n t a t o ss e tn o m e = ? ,e m a i l = ? , e n d e r e c o = ? , "+ 3 " d a t a N a s c i m e n t o = ?w h e r ei d = ? " ;
1

t r y{ 5 P r e p a r e d S t a t e m e n ts t m t= c o n n e c t i o n . p r e p a r e S t a t e m e n t ( s q l ) ; 6 s t m t . s e t S t r i n g ( 1 ,c o n t a t o . g e t N o m e ( ) ) ; 7 s t m t . s e t S t r i n g ( 2 ,c o n t a t o . g e t E m a i l ( ) ) ; 8 s t m t . s e t S t r i n g ( 3 ,c o n t a t o . g e t E n d e r e c o ( ) ) ; 9 s t m t . s e t D a t e ( 4 ,n e wD a t e ( c o n t a t o . g e t D a t a N a s c i m e n t o ( ) 1 0 . g e t T i m e I n M i l l i s ( ) ) ) ; 1 1 s t m t . s e t L o n g ( 5 ,c o n t a t o . g e t I d ( ) ) ; 1 2 s t m t . e x e c u t e ( ) ; 1 3 s t m t . c l o s e ( ) ; 1 4 }c a t c h( S Q L E x c e p t i o ne ){ 1 5 t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; 1 6 } 1 7 }
4

No existe nada de novo nas linhas acima. Uma execuo de query! Simples, no? O cdigo para remoo: comea com uma query baseada em um contato, mas usa somente o id dele para executar a query do tipo delete:
p u b l i cv o i dr e m o v e ( C o n t a t oc o n t a t o ){ 2 t r y{ 3 P r e p a r e d S t a t e m e n ts t m t= c o n n e c t i o n . p r e p a r e S t a t e m e n t ( " d e l e t e "+ 4 " f r o mc o n t a t o sw h e r ei d = ? " ) ; 5 s t m t . s e t L o n g ( 1 ,c o n t a t o . g e t I d ( ) ) ; 6 s t m t . e x e c u t e ( ) ; 7 s t m t . c l o s e ( ) ; 8 }c a t c h( S Q L E x c e p t i o ne ){ 9 t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; 1 0 } 1 1 }
1

2.17 - EXERCCIOS OPCIONAIS - ALTERAR E REMOVER


1. Adicione o mtodo para alterar contato no seu C o n t a t o D a o .

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9

p u b l i cv o i da l t e r a ( C o n t a t oc o n t a t o ){ S t r i n gs q l=" u p d a t ec o n t a t o ss e tn o m e = ? ,e m a i l = ? , " + " e n d e r e c o = ? ,d a t a N a s c i m e n t o = ?w h e r ei d = ? " ; t r y{ P r e p a r e d S t a t e m e n ts t m t=c o n n e c t i o n . p r e p a r e S t a t e m e n t ( s q l ) ; s t m t . s e t S t r i n g ( 1 ,c o n t a t o . g e t N o m e ( ) ) ; s t m t . s e t S t r i n g ( 2 ,c o n t a t o . g e t E m a i l ( ) ) ; s t m t . s e t S t r i n g ( 3 ,c o n t a t o . g e t E n d e r e c o ( ) ) ; s t m t . s e t D a t e ( 4 ,n e wD a t e ( c o n t a t o . g e t D a t a N a s c i m e n t o ( ) . g e t T i m e I n M i l l i s ( ) ) ) ; s t m t . s e t L o n g ( 5 ,c o n t a t o . g e t I d ( ) ) ; s t m t . e x e c u t e ( ) ; s t m t . c l o s e ( ) ; }c a t c h( S Q L E x c e p t i o ne ){ t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; } }

2. Adicione o mtodo para remover contato no seu C o n t a t o D a o


p u b l i cv o i dr e m o v e ( C o n t a t oc o n t a t o ){ 2 t r y{ 3 P r e p a r e d S t a t e m e n ts t m t=c o n n e c t i o n 4 . p r e p a r e S t a t e m e n t ( " d e l e t ef r o mc o n t a t o sw h e r e i d = ? " ) ; 5 s t m t . s e t L o n g ( 1 ,c o n t a t o . g e t I d ( ) ) ; 6 s t m t . e x e c u t e ( ) ; 7 s t m t . c l o s e ( ) ; 8 }c a t c h( S Q L E x c e p t i o ne ){ 9 t h r o wn e wR u n t i m e E x c e p t i o n ( e ) ; 1 0 } 1 1 }
1

3. Use os mtodos criados anteriormente para fazer testes com o seu banco de dados: atualize e remova um contato. 4. Crie uma classe chamada Funcionario com os campos id (Long), nome, usuario e senha (String). 5. Crie uma tabela no banco de dados chamada funcionarios.

6. Crie uma classe DAO para Funcionario. 7. Use-a para instanciar novos funcionrios e coloc-los no seu banco.

Seus livros de tecnologia parecem do sculo passado? Conhea a Casa do Cdigo, uma nova editora, com autores de destaque no mercado, foco em ebooks (PDF, epub, mobi), preos imbatveis e assuntos atuais. Com a curadoria da Caelum e excelentes autores, uma abordagem diferente para livros de tecnologia no Brasil. Conhea os ttulos e a nova proposta, voc vai gostar. Casa do Cdigo, livros para o programador.

CAPTULO ANTERIOR:

PRXIMO CAPTULO:

Enfrentando o Java na Web

O que Java EE?

Voc encontra a Caelum tambm em:

Blog Caelum

Cursos Online

Facebook

Newsletter

Casa do Cdigo

Twitter