Escolar Documentos
Profissional Documentos
Cultura Documentos
On-Line
Alfamdia Prow
http://www.alfamidia.com.br
Sumrio
Captulo 1 O Bsico ........................................................................................ 4
Criando Um Banco de Dados de Exemplo................................................................................ 4
Drivers JDBC ............................................................................................................................ 5
Instalando o Driver no seu Projeto ........................................................................................ 5
A Rotina de Uso da API JDBC ............................................................................................... 10
Captulo 1 O Bsico
JDBC significa Java Database Connectivity (conectividade com bancos de dados em Java).
uma API para a Linguagem Java que define como um cliente pode acessar um banco de dados.
A API focada em bancos de dados relacionais e foi lanada em 19 de Fevereiro de 1997, como
parte do Java Development Kit 1.1.
Embora a plataforma j tenha nascido preparada para lidar com todo tipo de banco de dados
relacional, na poca era oferecida apenas uma implementao de referncia da Bridge ODBCJDBC, o que permitia que programas escritos em Java acessassem qualquer fonte de dados
ODBC ao alcance do ambiente hospedeiro da JVM.
JDBC permite que mltiplas implementaes coexistam e possam ser usadas na mesma
aplicao. A API prov um mecanismo para carregar dinamicamente os pacotes Java
necessrios conexo com um determinado banco de dados e para registrar estes pacotes frente
classe DriverManager, que usada como Factory para se obter as conexes com os mesmos.
As instrues suportadas incluem CREATE, INSERT, UPDATE, DELETE e SELECT. H
inclusive a possibilidade de se chamarem Stored Procedures.
Drivers JDBC
Os Drivers JDBC so adaptadores instalados no lado cliente que convertem as requisies feitas
por meio da API JDBC para um protocolo capaz de ser entendido pelo banco de dados de
destino.
Existem drivers comerciais e gratuitos para os mais diversos formatos de bancos de dados.
Cada um destes drivers cai em uma das quatro categorias disponveis:
Tipo 1
Tipo 2
Tipo 3
Tipo 4
Tipo
Nome
Java Puro
Protocolo de Rede
Descrio
Tipo 1
Bridge
ODBC
Direto
Tipo 2
API Nativa
No
Direto
Tipo 3
JDBC Net
Sim
Requer Conector
Tipo 4
Direto
Sim
Direto
JDBC- No
Conector/J o nome comercial do driver JDBC do MySQL. Clique em DOWNLOAD para baixlo.
Quando a prxima pgina surgir, escolha o formato que lhe mais conveniente (tipicamente,
usurios do Windows escolhero o formato .zip, enquanto que usurios do Linux escolhero o
formato .tar).
Salve o arquivo em um diretrio do seu disco rgido, por exemplo, e depois, usando o Windows
Explorer, navegue at aquele local.
O arquivo .jar que extramos o arquivo que contm as classes Java que so necessrias para
conectar a um banco de dados MySQL. Com o arquivo salvo em algum lugar, agora hora de
acrescent-lo ao seu projeto. Nas imagens abaixo mostraremos o processo usando o NetBeans,
nas o processo no muito diferente se voc estiver usando outro IDE, como o Eclipse por
exemplo.
Depois de abrir o NetBeans e criar o seu projeto, clique com o boto direito sobre ele no Project
Explorer e selecione a opo Propriedades. Com a janela Propriedades do projeto
aberta, clique em Bibliotecas. Voc ver algo parecido com a tela mostrada abaixo.
Agora clique no boto Adicionar JAR/pasta para que possa selecionar o arquivo .jar
que extramos.
Navegue at o diretrio onde voc salvou o arquivo .jar e selecione-o, clicando em Abrir
em seguida.
10
Neste captulo veremos um pouco do que necessrio para que possamos criar aplicaes que
utilizem a API JDBC.
11
Descrio
void close()
void commit()
Statement createStatement()
boolean isClosed()
Mtodo
Descrio
boolean isReadOnly()
boolean isValid()
PreparedStatement
sql)
void rollback()
ConectandoAoBanco.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConectandoAoBanco {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Driver no encontrado.");
return;
}
Connection con = null;
try {
con = DriverManager.getConnection(
"jdbc:mysql://localhost/agendatelefonica",
"agenda", "agenda");
// Voc colocaria aqui o cdigo que faz uso do banco.
} catch (SQLException sqle) {
System.out.println("Incapaz de conectar.");
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
}
}
}
13
Java oferece trs interfaces principais para enviar comandos ao banco de dados:
Statement
PreparedStatement
CallableStatement
A Interface Statement
Objetos do tipo java.sql.Statement so criados ao se chamar o mtodo
createStatement() do objeto Connection.
Objetos deste tipo so usados para executar comandos SQL estticos e obter os resultados que
eles produzem, seja por meio de valores primitivos ou por meio de um objeto
java.sql.ResultSet (primitivos so retornados quando o comando em questo apenas
informa o sucesso ou o nmero de registros afetados; um ResultSet retornado quando uma
query retorna o grupo de registros selecionados pelo seu critrio de filtro).
Os mtodos abaixo podem ser utilizados:
Mtodo
Descrio
void close()
ResultSet getGeneratedKeys()
boolean isClosed()
FazendoUmInsert.java
import java.sql.Connection;
14
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class FazendoUmInsert {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Driver no encontrado.");
return;
}
Connection con = null;
try {
con = DriverManager.getConnection(
"jdbc:mysql://localhost/agendatelefonica",
"agenda", "agenda");
Statement stmt = con.createStatement();
int incluidos = stmt.executeUpdate(
"insert into pessoa(nome, ddd, telefone) "
+ "values ('Joo Silveira', '51', "
+ "'3030-1313')");
} catch (SQLException sqle) {
System.out.println("Erro de SQL: " + sqle);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
}
}
}
A Interface ResultSet
Um ResultSet agrega os dados recuperados a partir do banco de dados em uma estrutura
semelhante a um iterator de uma coleo. Ele geralmente obtido por meio de instrues que
consultam o banco, como as Statement e PreparedStatement, mas tambm pode ser
retornado por instncias de CallableStatement.
O ResultSet possui um cursor que aponta para a linha corrente dentro da lista de resultados.
Este cursor inicialmente est posicionado na linha anterior primeira linha de dados.
Normalmente ResultSets so navegveis apenas para a frente e no so atualizveis.
Mtodos factory especiais em Connection permitem que ResultSet navegveis e
atualizveis sejam criados, mas eles normalmente consumem muito mais recursos do banco e
no so muito utilizados.
Apenas um ResultSet pode estar aberto por cada Statement, PreparedStatement ou
CallableStatement, ento mltiplos objetos sero necessrios no caso de se fazerem
consultas encadeadas.
15
Descrio
BigDecimal
parameterIndex)
ResultSetMetaData getMetaData()
Boolean getMoreResults()
int getRow()
Timestamp
parameterIndex)
boolean isAfterLast()
Mtodo
Descrio
boolean isBeforeFirst()
boolean isClosed()
boolean isFirst()
boolean isLast()
boolean next()
FazendoUmSelect.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class FazendoUmSelect {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Driver no encontrado.");
return;
}
Connection con = null;
try {
con = DriverManager.getConnection(
"jdbc:mysql://localhost/agendatelefonica",
"agenda", "agenda");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select id, nome "
+ "from pessoa order by nome, id");
while (rs.next()) {
System.out.print(rs.getInt("id"));
System.out.print(": ");
System.out.println(rs.getString("nome"));
}
} catch (SQLException sqle) {
System.out.println("Erro de SQL: " + sqle);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
17
}
}
}
A Interface ResultSetMetaData
Por meio da interface ResultSetMetaData pode-se descobrir a quantidade e tipo de dados
de cada coluna que seria/foi retornada por uma query. Com isso poderamos criar utilitrios ou
programas que lidam com dados sobre os quais nada se sabe de antemo, exatamente como o
PHPMyAdmin ou o Navicat fazem.
Obtm-se um ResultSetMetaData ao se chamar o mtodo getMetaData() de uma
instncia de PreparedStatement, CallableStatement ou ResultSet.
A tabela abaixo exibe os mtodos mais utilizados em ResultSetMetaData:
Mtodo
Descrio
int getColumnCount()
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql. Statement;
public class BuscandoOsMetaDados {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Driver no encontrado.");
return;
}
Connection con = null;
try {
con = DriverManager.getConnection(
"jdbc:mysql://localhost/agendatelefonica",
"agenda", "agenda");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select id, nome "
+ "from pessoa order by nome, id");
ResultSetMetaData rsmd = rs.getMetaData();
int numeroDeCampos = rsmd.getColumnCount();
for (int i = 1; i <= numeroDeCampos; i++) {
System.out.print(rsmd.getTableName(i));
System.out.print(".");
System.out.print(rsmd.getColumnName(i));
System.out.print("\t");
System.out.print(rsmd.getColumnTypeName(i));
System.out.print("(");
System.out.print(rsmd.getPrecision(i));
System.out.println(")");
}
} catch (SQLException sqle) {
System.out.println("Erro de SQL: " + sqle);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
}
}
}
19
A Interface PreparedStatement
Objetos do tipo java.sql.PreparedStatement so obtidos ao se chamar o mtodo
prepareStatement(String sql) do objeto Connection.
Objetos deste tipo so usados para se executar comandos SQL pr-compilados, o que os tornam
especialmente eficientes quando executados mltiplas vezes. Os diferentes mtodos set()
podem ser usados para popular os parmetros da PreparedStatement depois da
compilao da query, possibilitando tornar cada execuo nica.
Mtodo
Descrio
void clearParameters()
ResultSet executeQuery()
int executeUpdate()
ResultSetMetaData getMetaData()
ParameterMetaData getParameterMetaData()
void
setBigDecimal(int
BigDecimal x)
Mtodo
Descrio
void
setTimestamp(int
Timestamp x)
FazendoOutroInsert.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class FazendoOutroInsert {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Driver no encontrado.");
return;
}
Connection con = null;
try {
con = DriverManager.getConnection(
"jdbc:mysql://localhost/agendatelefonica",
"agenda", "agenda");
PreparedStatement ps = con.
prepareStatement("insert into pessoa "
21
22
Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "Mariana Ferreira");
ps.setString(2, "51");
ps.setString(3, "3030-2020");
int registrosIncluidos = ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
rs.next();
int idGerado = rs.getInt("GENERATED_KEY");
System.out.println("O ID gerado foi " + idGerado);
} catch (SQLException sqle) {
System.out.println("Erro de SQL: " + sqle);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
}
}
}
24
A Interface CallableStatement
Objetos do tipo java.sql.CallableStatement so obtidos ao se chamar o mtodo
prepareCall(String sql) do objeto Connection.
Objetos deste tipo so usados para se executar stored procedures no banco. Um stored
procedure pode retornar nenhum, um ou muitos ResultSets. Mltiplos ResultSets so
tratados atravs dos mtodos getResultSet() e getMoreResults().
A API oferece uma sintaxe que permite que stored procedures sejam chamados de uma maneira
consistente, independentemente da plataforma de banco de dados subjacente. H uma sintaxe
para stored procedures que retornam valores e outra para aquelas que no retornam:
{?=
call
<nome-da-stored-procedure>[(<arg1>,
<arg2>,
...)]}
{call <nome-da-stored-procedure>[(<arg1>, <arg2>, ...)]}
Descrio
boolean execute()
BigDecimal
parameterIndex)
Mtodo
Descrio
Boolean getMoreResults()
ResultSet getResultSet()
Timestamp
parameterIndex)
void
registerOutParameter(int Registra o parmetro de sada de ndice
parameterIndex, int sqlType)
indicado com o tipo de dados SQL
especificado,
conforme
a
classe
java.sql.Types.
void
setBigDecimal(int
BigDecimal x)
26
Mtodo
Descrio
void
setTimestamp(int
Timestamp x)
"{call listaPessoas()}");
ResultSet rs = cs.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("nome"));
}
} catch (SQLException sqle) {
System.out.println("Erro de SQL: " + sqle);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
}
}
}
import java.sql.Types;
public class ContaPessoas {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException cnfe) {
System.out.println("Driver no encontrado.");
return;
}
Connection con = null;
try {
con = DriverManager.getConnection(
"jdbc:mysql://localhost/agendatelefonica",
"agenda", "agenda");
CallableStatement cs = con.prepareCall(
"{? = call contaPessoas()}");
cs.registerOutParameter(1, Types.INTEGER);
cs.execute();
int pessoas = cs.getInt(1);
System.out.println(pessoas);
} catch (SQLException sqle) {
System.out.println("Erro de SQL: " + sqle);
} finally {
try {
if (con != null) {
con.close();
}
} catch (SQLException ignore) {
// Nada a fazer.
}
}
}
}
Repare no uso de cs.registerOutParameter(1, Types.INTEGER), que serve para
indicar a existncia de um parmetro de sada (a primeira interrogao na String que define a
query) do tipo integer. Depois de executarmos a query podemos ler o valor daquele retorno
usando cs.getInt(1).
where
order
limit
END;
//
DELIMITER
recebe quanto devolve valores por meio deste parmetro), tambm precisamos registr-lo como
um parmetro de sada (com cs.registerOutParameter(1, Types.VARCHAR)).
Note que o nmero 1 em ambos os casos indica ao engine que estamos nos referindo ao
primeiro sinal de interrogao da query.
Depois de executarmos o stored procedure podemos recuperar o valor devolvido pelo mesmo
como se estivssemos lendo dados de um ResultSet (no exemplo, cs.getString(1)).
mvfm, 2012-02-02, Alfamdia
32
Os Objetos de Acesso a Dados (DAO, de Data Access Objects em ingls) constituem uma
parte essencial na arquitetura de uma boa aplicao.
Aplicaes corporativas quase sempre precisam acessar dados a partir de um banco de dados
relacional, e a plataforma Java oferece muitas maneiras de acessar a estes dados. A mais antiga
e mais madura destas tcnicas a API de Java Database Conectivity (JDBC), a qual prov a
capacidade de executar queries SQL em um banco de dados e de recuperar os seus resultados,
uma coluna por vez.
O Design Pattern DAO oferece a flexibilidade de mudar o mecanismo de persistncia de uma
aplicao sem que haja a necessidade de se reprojetar a lgica da aplicao que interage com a
API de persistncia escolhida.
Por exemplo, pode haver benefcios de performance ao se trocar o mecanismo de persistncia de
EJB para chamadas diretas ao JDBC, ou mesmo a mudana para um outro sistema de
persistncia como Spring ou JPA.
Sem uma camada DAO este tipo de transio provocaria enormes modificaes no seu cdigo.
O padro tambm oferece benefcios ao no exigir que seu utilizador conhea todos os
meandros do mecanismo de persistncia escolhido.
33
No exemplo acima demonstramos uma aplicao em que o acesso ao banco de dados feito
diretamente a partir da lgica de negcio. Esta parece a maneira mais natural de se resolver o
problema, porm ela tem desvantagens importantes. Note que a aplicao envia diretamente
comandos SQL para o driver JDBC, bem como recebe retornos do tipo ResultSet ou
excees do tipo SQLException: se voc trocar a tecnologia de persistncia (por JPA ou EJB,
por exemplo), os tipos de dados certamente sero outros. Modifique a camada de persistncia e
seja obrigado a modificar toda sua lgica de negcio.
O objetivo do design-pattern DAO justamente tornar a substituio do mecanismo de
persistncia transparente do ponto de vista da aplicao.
O que queremos fazer evitar o contato direto entre a lgica de negcios e o engine JDBC.
Fazemos isso por meio do acrscimo de uma camada de intermediria, o nosso componente
DAO. A camada de negcios se comunicar com o DAO por meio de beans (objetos que
representam registros individuais) ou colees de beans ao invs de queries SQL ou
ResultSets, e excees customizadas (que substituem ou encapsulam as SQLExceptions
ou outras excees dependentes da tecnologia de persistncia em uso).
A seguir detalharemos melhor cada um dos componentes da arquitetura proposta.
A Classe de Bean
O bean uma classe Java comum (um POJO, de Plain Old Java Object) que representa uma
entidade na sua aplicao. Tipicamente os beans apresentam uma paridade de 1:1 com as
tabelas do banco de dados (para cada tabela existir um bean). O seu propsito representar um
registro naquela tabela, apresentando mtodos getters e setters e eventuais construtores para
convenincia.
importante que este objeto implemente tambm os mtodos equals() e hashCode(), j
que normalmente ele ser usado em colees. E o mtodo toString() um plus, pois ajuda
bastante no momento do debug.
O estado inicial do bean fica ao seu critrio: alguns preferem ser mais semanticamente precisos
e evitam fornecer valores default para os atributos, j que pode ser que os campos realmente
34
devam ser null. Outros acham mais conveniente inicializar os atributos com os valores vazios
pertinentes, como demonstrado a seguir.
Pessoa.java
public class Pessoa {
private int id = 0;
private String nome = "";
private String endereco = "";
private String cidade = "";
private String estado = "";
private String cep = "";
private String ddd = "";
private String telefone = "";
public Pessoa() {
}
public Pessoa(int id) {
this.id = id;
}
public Pessoa(String nome) {
this.nome = nome;
}
public Pessoa(int id, String nome) {
this.id = id;
this.nome = nome;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getEndereco() {
return endereco;
}
public void setEndereco(String endereco) {
this.endereco = endereco;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public String getEstado() {
return estado;
}
public void setEstado(String estado) {
35
this.estado = estado;
}
public String getCep() {
return cep;
}
public void setCep(String cep) {
this.cep = cep;
}
public String getDdd() {
return ddd;
}
public void setDdd(String ddd) {
this.ddd = ddd;
}
public String getTelefone() {
return telefone;
}
public void setTelefone(String telefone) {
this.telefone = telefone;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Pessoa other = (Pessoa) obj;
if (this.id != other.id) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 3;
hash = 31 * hash + this.id;
return hash;
}
@Override
public String toString() {
return "Pessoa{" + "id=" + id + ", nome=" + nome
+ ", endereco=" + endereco + ", cidade="
+ cidade + ", estado=" + estado + ", cep="
+ cep + ", ddd=" + ddd + ", telefone="
+ telefone + '}';
}
}
36
A Classe DAOException
A classe DAOException ser usada para representar uma exceo customizada que ocorreu
dentro da camada DAO. Ela serve para empacotar instncias de excees dependentes da
camada de persistncia corrente, evitando assim que as classes clientes precisem tomar
conhecimento das mesmas. Se o quiserem, no entanto, podem faz-lo por meio do mtodo
getCause().
DAOException.java
public class DAOException extends Exception {
public DAOException(Throwable cause) {
super(cause);
}
public DAOException(String message, Throwable cause) {
super(message, cause);
}
public DAOException(String message) {
super(message);
}
public DAOException() {
}
}
A Classe DAO
A classe DAO serve como base para a nossa camada de DAO. Ela define os mtodos
getConnection() e closeConnection(), alm das constantes que, de outra forma,
estariam espalhadas pelo cdigo (nome do driver de banco, url do mesmo, usurio, senha ...).
uma classe abstrata, pois nunca a instanciaremos diretamente.
Tambm fica fcil alter-la para se fazer uso de um servio de pool de conexes, por exemplo.
DAO.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public abstract class DAO {
private static final String JDBC_DRIVER =
"com.mysql.jdbc.Driver";
private static final String JDBC_URL =
"jdbc:mysql://localhost/agendatelefonica";
private static final String JDBC_USUARIO = "agenda";
private static final String JDBC_SENHA = "agenda";
private static boolean preparado = false;
public static Connection getConnection()
throws SQLException, DAOException {
if (!preparado) {
try {
Class.forName(JDBC_DRIVER);
preparado = true;
} catch (ClassNotFoundException cnfe) {
System.out.println("Incapaz de carregar o driver "
+ "JDBC: " + cnfe);
37
A Classe PessoaDAO
A classe concreta de DAO. Para cada tabela no banco teremos uma classe DAO
correspondente. Esta classe ser a responsvel por desempenhar todas as operaes de banco
com esta entidade, ento ela tipicamente declarar mtodos como incluir(), alterar() e
excluir(), alm dos mtodos de pesquisa que se mostrarem necessrios.
PessoaDAO.java
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class PessoaDAO extends DAO {
private static final String SQL_INCLUIR = "insert into "
+ "pessoa (nome, endereco, cidade, estado, cep, "
+ "ddd, telefone) values (?, ?, ?, ?, ?, ?, ?)";
private static final String SQL_ALTERAR = "update pessoa "
+ "set nome = ?, endereco = ?, cidade = ?, "
+ "estado = ?, cep = ?, ddd = ?, telefone = ? "
+ "where id = ?";
private static final String SQL_EXCLUIR = "delete from "
+ "pessoa where idx = ?";
private static final String SQL_BUSCAR_TODOS = "select "
+ "id, nome, endereco, cidade, estado, cep, ddd, "
+ "telefone from pessoa order by nome";
private static final String SQL_BUSCAR_POR_NOME = "select "
+ "id, nome, endereco, cidade, estado, cep, ddd, "
+ "telefone from pessoa where nome like ? order "
+ "by nome";
public static final String SQL_BUSCAR_POR_ID = "select "
+ "id, nome, endereco, cidade, estado, cep, ddd, "
+ "telefone from pessoa where id = ?";
38
em "
+ sqle);
SQL em "
+ sqle, sqle);
}
public List<Pessoa> buscarTodas() throws DAOException {
List<Pessoa> pessoas = new ArrayList();
Connection con = null;
try {
con = getConnection();
PreparedStatement ps = con.prepareStatement(
SQL_BUSCAR_TODOS);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
pessoas.add(lePessoa(rs));
}
} catch (SQLException sqle) {
System.out.println("Erro de SQL em "
+ "PessoaDAO.buscarTodos: " + sqle);
throw new DAOException("Erro de SQL em "
+ "PessoaDAO.buscarTodos: " + sqle, sqle);
} finally {
closeConnection(con);
}
return pessoas;
}
public List<Pessoa> buscarPorNome(Pessoa criterio)
throws DAOException {
List<Pessoa> pessoas = new ArrayList();
Connection con = null;
try {
con = getConnection();
PreparedStatement ps = con.prepareStatement(
SQL_BUSCAR_POR_NOME);
populaQuery(ps, criterio, QUERY_SO_COM_NOME);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
pessoas.add(lePessoa(rs));
}
} catch (SQLException sqle) {
System.out.println("Erro de SQL em "
+ "PessoaDAO.buscarPorNome: " + sqle);
throw new DAOException("Erro de SQL em "
+ "PessoaDAO.buscarPorNome: " + sqle, sqle);
} finally {
40
closeConnection(con);
}
return pessoas;
}
public Pessoa buscarPorId(Pessoa criterio)
throws DAOException {
Connection con = null;
try {
con = getConnection();
PreparedStatement ps = con.prepareStatement(
SQL_BUSCAR_POR_ID);
populaQuery(ps, criterio, QUERY_SO_COM_ID);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
return lePessoa(rs);
} else {
throw new DAOException("O registro com ID "
+ criterio.getId()
+ " no foi encontrado.");
}
} catch (SQLException sqle) {
System.out.println("Erro de SQL em "
+ "PessoaDAO.buscarPorNome: " + sqle);
throw new DAOException("Erro de SQL em "
+ "PessoaDAO.buscarPorNome: " + sqle, sqle);
} finally {
closeConnection(con);
}
}
private static void populaQuery(PreparedStatement ps,
Pessoa pessoa, int tipoDeQuery)
throws SQLException {
if (tipoDeQuery == QUERY_COM_ID
|| tipoDeQuery == QUERY_SEM_ID) {
ps.setString(1, pessoa.getNome());
ps.setString(2, pessoa.getEndereco());
ps.setString(3, pessoa.getCidade());
ps.setString(4, pessoa.getEstado());
ps.setString(5, pessoa.getCep());
ps.setString(6, pessoa.getDdd());
ps.setString(7, pessoa.getTelefone());
}
if (tipoDeQuery == QUERY_COM_ID) {
ps.setInt(8, pessoa.getId());
} else if (tipoDeQuery == QUERY_SO_COM_ID) {
ps.setInt(1, pessoa.getId());
} else if (tipoDeQuery == QUERY_SO_COM_NOME) {
ps.setString(1, "%" + pessoa.getNome() + "%");
}
}
private static Pessoa lePessoa(ResultSet rs)
throws SQLException {
Pessoa pessoa = new Pessoa();
41
pessoa.setId(rs.getInt("id"));
pessoa.setNome(rs.getString("nome"));
pessoa.setEndereco(rs.getString("endereco"));
pessoa.setCidade(rs.getString("cidade"));
pessoa.setEstado(rs.getString("estado"));
pessoa.setCep(rs.getString("cep"));
pessoa.setDdd(rs.getString("ddd"));
pessoa.setTelefone(rs.getString("telefone"));
return pessoa;
}
}
42