Baixar slides - Blog UNIFIMES

Propaganda
JavaServer Faces – JSF
Fernando Freitas Costa
Bacharel em Sistemas de Informação
Especialista em Gestão e Docência Universitária
blog.fimes.edu.br/fernando
[email protected]
JavaServer Faces
e
Banco de Dados
Connection

Para trabalhar com Banco de Dados
(MySQL) em JSF, é necessário
primeiramente ter um objeto connection,
que pode ser obtido com a sintaxe a
seguir:
Connection conn =
DriverManager.getConnection(“jdbc:mysql://url:porta/nomeBanco
”, “usuario”, “senha”);
Statement

Depois de obter o objeto connection, é necessário criar um
objeto da interface java.sql.Statement, que permitirá o envio
dos comandos SQL ao banco de dados.
Statement stmt = conn.createStatement();

A interface java.sql.Statement possui entre outros, os métodos:
◦ executeUpdate – envia comandos SQL que atualizam o banco de
dados. Retorna um inteiro com o número de registros afetados. Ex:
int x = stmt.executeUpdate(“insert into usuario (id, nome, senha) values(1, ‘paulo’, ‘123’)”);
◦ executeQuery – envia comandos SQL que consultam o banco de
dados. Retorna um ResultSet. Ex:
ResultSet rs = stmt.executeQuery(“select * from usuario”);
ResultSet

Um ResultSet é como uma tabela de dados que representa um
conjunto de registros obtidos de um banco de dados, geralmente pela
execução de consultas em um objeto statement.

A interface java.sql.ResultSet possui alguns métodos de navegação
entre os registros obtidos:
◦ first() - posiciona o cursor no primeiro registro do objeto ResultSet.
◦ last() - posiciona o cursor no último registro do objeto ResultSet.
◦ next() -posiciona o cursor no próximo registro do objeto ResultSet. Retorna
false se não houver próximo.
◦ previous() - posiciona o cursor no registro anterior do objeto ResultSet.
◦ etc...
ResultSet

Para obter os dados de um registro, devemos chamar um dos
seguintes métodos da interface java.sql.ResultSet:
◦ getString() – Obtém informações do tipo String;
◦ getInt() – Obtém informações do tipo Inteiro;
◦ getDouble() – Obtém informações do tipo double
◦ E assim sucessivamente de acordo com o tipo de dado a ser obtido.

Exemplo:
while(rs.next()){
Integer id = rs.getInt(“id”);
String nome = rs.getString(“nome”);
String senha = rs.getString(“senha”);
}
Fechando Conexões

Após terminar o acesso ao banco de dados, é sempre bom fechar a conexão.
Para garantir que ela seja fechada em qualquer situação, mesmo em caso de
exceções, coloque o método close() dentro de um bloco try/catch/finally.

Uma boa prática neste ponto, é criar blocos try separados para tratar a
conexão e para tratar as demais exceções. Ex:
try{
Connection conn = DriverManager.getConnection(“jdbc:mysql://url:porta/nomeBanco”, “usuario”,
“senha”);
try{
Statement stmt = conn.createStatement();
int x = stmt.executeUpdate(“insert into usuario (id, nome, senha) values(1, ‘paulo’, ‘123’)”);
}finally{
conn.close();
}
}catch(SQLException e){
...
}
 Outra opção melhor ainda, é definir seu método para lançar SQLException e
deixar que o chamador trate estas exceções.
PreparedStatement

Quando a aplicação precisa emitir várias vezes o mesmo comando SQL apenas
com valores diferentes, uma opção mais rápida para trabalhar com o banco de
dados é fazer uso da interface java.sql.PreparedStatement.

Um objeto PreparedStatement solicita ao banco que uma query seja précompilada. Feito isto, ela é mantida e reutilizada sempre que ela for
submetida novamente.

Outra boa razão para trabalhar com esta interface é evitar que entradas de
usuário se transformem em SQL Injection (ataque a uma aplicação via código
SQL).

O primeiro passo é criar um objeto da interface java.sql.PreparedStatement,
que permitirá o envio dos comandos SQL ao banco de dados.
PreparedStatement pstmt = conn.preparedStatement(“instrução sql com parâmetros”);
PreparedStatement

Para aceitar valores diferentes o objeto PreparedStatement trabalha com o
uso de parâmetros (representados pelo ponto de interrogação), que são
definidos no momento da execução. Ex:
PreparedStatement pstmt = conn.preparedStatement(“select * from usuario where nome like ?”);
pstmt.setString(1, ‘fernando’);
ResultSet rs = pstmt.executeQuery();

Para definir os valores de cada parâmetro a interface
java.sql.PreparedStatement fornece os métodos:
◦ setString() – Define parâmetros do tipo String;
◦ setInt() – Define parâmetros do tipo Integer/int.
◦ setDouble() – Define parâmetros do tipo Double/double.
◦ E assim sucessivamente, de acordo com o tipo do parâmetro a ser definido.
◦ Estes métodos recebem dois parâmetros:
 O primeiro é um número referente a qual ponto de interrogação você está se referindo (1º,
2º, 3º, ...).
 O segundo é o valor que deve ser atribuído ao parâmetro.
PreparedStatement

Assim como a interface java.sql.Statement, a interface
java.sql.PreparedStatement também possui entre outros, os métodos:
◦ executeUpdate – envia comandos SQL que atualizam o banco de dados. Retorna um
inteiro com o número de registros afetados. Ex:
PreparedStatement pstmt = conn.preparedStatement(“insert into usuario (id, nome, senha) values
(?, ?, ?)”);
pstmt.setInt(1, 1);
pstmt.setString(2, ‘fernando’);
pstmt.setString(3, ’123’);
Integer resultado = pstmt.executeUpdate();
◦ executeQuery – envia comandos SQL que consultam o banco de dados. Retorna um
ResultSet. Ex:
PreparedStatement pstmt = conn.preparedStatement(“select * from usuario where nome like ?”);
pstmt.setString(1, ‘fernando’);
ResultSet rs = pstmt.executeQuery();
Transações
Ao trabalhar com banco de dados, pode ser necessário
utilizar o conceito de transações para confirmar ou
reverter uma ou mais comandos SQL.
 O uso de transações é bom por duas razões: integridade e
acesso concorrente.
 Por padrão, uma conexão com o banco trabalha no modo
autocommit, ou seja, confirma cada comando
separadamente. Portanto, ao trabalhar com transações, o
primeiro passo é desativar este padrão. Ex:

conn.setAutoCommit(false);
Transações

Se durante a transação tudo correr bem, deve-se efetuar um commit
ao final do processo. Ex:
conn.commit();

Caso contrário, deve-se efetuar um rollback na transação. Ex:
conn.rollback ();

O exemplo a seguir mostra como lidar com transações:
conn.setAutoCommit(false);
boolean commited = false;
try{
//operações no banco de dados
conn.commit();
commited = true;
}finally{
if (!commited) conn.rollback();
}
Exemplo Prático
JSF e Banco de Dados
Crie um novo Dinamic Web Project com o
nome ExemploBD01;
 Em seguida, devemos fazer estes 6
passos.

◦
◦
◦
◦
◦
◦
Criação do banco de dados;
Criação das tabelas;
Criação da classe DAO;
Criação da classe Bean;
Mapeamento da classe Bean;
Criação da página JSF.
Passos 1 e 2 – Criação do Banco e da tabela
create database jsf_bd;
use jsf_bd;
create table usuario(
id integer not null auto_increment,
nome varchar(50) not null,
email varchar(50),
fone varchar(13) not null,
primary key (id)
) engine = InnoDB;
Passo 3 – Criação da classe Bean


Crie o pacote bean.
Crie uma classe chamada UsuarioBean. Ela será o meio termo entre o
dao e a página JSF.
package bean;
import javax.faces.bean.ManagedBean;
import dao.UsuarioDAO;
@ManagedBean
public class UsuarioBean {
private Integer id;
private String nome, fone, email;
public
public
public
public
public
public
public
public
Integer getId() { return id; }
void setId(Integer id) { this.id = id; }
String getNome() { return nome; }
void setNome(String nome) { this.nome = nome; }
String getFone() { return fone; }
void setFone(String fone) { this.fone = fone; }
String getEmail() { return email; }
void setEmail(String email) { this.email = email; }
public String salvar(){
UsuarioDAO uDao = new UsuarioDAO();
int resultado = uDao.salvar(this);
if(resultado > 0){
this.nome = "";
this.fone = "";
this.email = "";
}
return null;
}
}
Passo 4 – Criação da classe DAO

Crie um pacote dao

Crie uma classe chamada UsuarioDAO. Ela será responsável por lidar diretamente com
o BD. Vejamos um exemplo simples:
package dao;
import
import
import
import
import
import
import
java.sql.Connection;
java.sql.DriverManager;
java.sql.SQLException;
java.sql.Statement;
javax.faces.application.FacesMessage;
javax.faces.context.FacesContext;
bean.UsuarioBean;
public class UsuarioDAO {
public int salvar(UsuarioBean ub) {
int resultado = 0;
FacesContext ctx = FacesContext.getCurrentInstance();
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsf_bd", "root", "vertrigo");
try {
Statement stmt = conn.createStatement();
resultado = stmt.executeUpdate("insert into usuario (nome, email, fone) values ('"+ ub.getNome()+ "', '"+
ub.getEmail()+ "', '" + ub.getFone() + "')");
ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Cadastro realizado com sucesso", "O
cadastro foi realizado com sucesso"));
} finally { conn.close(); }
} catch (ClassNotFoundException cnfex) {
ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erro: Classe não encontrada", "A classe
com.mysql.jdbc.Driver não foi encontrada. Detalhe: "+ cnfex.getMessage()));
} catch (SQLException sqlex) {
ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Ocorreu um erro ao salvar" , "Ocorreu
um erro ao executar a instrução SQL. Detalhe: "+ sqlex.getMessage()));
}
return resultado;
}
}
Passo 5 – Criação das páginas JSF

Crie uma nova página chamada index.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Insert title here</title>
</head>
<body>
<h:form>
<h:messages errorStyle="color:red" infoStyle="color:green" showDetail="true"/>
<h:panelGrid columns="3">
<h:outputLabel value="Nome:" for="nome"/>
<h:inputText id="nome" value="#{usuarioBean.nome}" required="true" requiredMessage="Informe o nome"/>
<h:message for="nome"/>
<h:outputLabel value="E-mail:" for="email"/>
<h:inputText id="email" value="#{usuarioBean.email}"/>
<h:message for="email"/>
<h:outputLabel value="Fone:" for="fone"/>
<h:inputText id="fone" value="#{usuarioBean.fone}" required="true" requiredMessage="Informe o telefone"/>
<h:message for="fone"/>
<h:commandButton action="#{usuarioBean.salvar()}" value="Salvar" />
</h:panelGrid>
</h:form>
</body>
</html>
Tente executar...

Funcionou?
Por quê não funcionou?
Não funcionou porque o Tomcat precisa que a classe
com.mysql.jdbc.Driver seja informada.
 Para isto, você vai precisar do Conector MySQL que
pode ser obtido no endereço:
http://dev.mysql.com/downloads/connector/j/
 Após baixá-lo, descompacte-o e copie o arquivo mysqlconnector-java-5.x.xx-bin.jar (onde o x refere-se as
subversões do conector MySQL), para dentro da pasta
WebContent/WEB-INF/lib


Pronto, agora sim, execute o arquivo.
Exercícios
1.
Com base no conteúdo passado, faça uma cópia deste
projeto e salve com o nome ExemploBD02. No
projeto ExemploBD02, faça as alterações para que ele
fique mais seguro, ou seja, utilize PreparedStatement
no lugar das Statement utilizada.
2.
Em seguida, crie uma página sucesso.xhtml que:
•
•
•
Deverá ser exibida em caso de sucesso ao cadastrar.
Deve exibir os dados recém cadastrados. (Atenção, estes dados devem ser
consultados no banco)
Coloque nela um botão Voltar.
Download