javaserver faces – jsf - blog unifimes – blog oficial...

21
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]

Upload: ngoliem

Post on 10-Nov-2018

280 views

Category:

Documents


0 download

TRANSCRIPT

JavaServer Faces – JSF

Fernando Freitas CostaBacharel em Sistemas de Informação

Especialista em Gestão e Docência Universitária

blog.fimes.edu.br/[email protected]

JavaServer Facese

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 commitao 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 dadosconn.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;

@ManagedBeanpublic class UsuarioBean {

private Integer id;private String nome, fone, email;

public Integer getId() { return id; }public void setId(Integer id) { this.id = id; }public String getNome() { return nome; }public void setNome(String nome) { this.nome = nome; }public String getFone() { return fone; }public void setFone(String fone) { this.fone = fone; }public String getEmail() { return email; }public 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 java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;import javax.faces.application.FacesMessage;import javax.faces.context.FacesContext;import 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/xhtml1-transitional.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 mysql-connector-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ícios1. 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 PreparedStatementno 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 serconsultados no banco)

• Coloque nela um botão Voltar.