Aprenda Java Web JSF

  • Página Inicial
  • Contato!
  • Tudo sobre Java Web JSF Parte 1!
  • Tudo sobre Java Web JSF Parte 2!
  • Tudo sobre Java Web JSF Parte 3!
  • Tudo sobre Java Web JSF Parte 4!
  • Tudo sobre Java Web JSF Parte 2

    Criando Templates

    Os templates são como uma "casca" que usaremos em nosso site, aplicando em todas as telas do nosso sistema, dessa forma, alterando apenas o template, alteramos a página toda de uma só vez.

    Crie um novo XHTML com o nome template para isso, de forma que tenha mais um atributo xmlns, assim:

    
    <?xml version="1.0" encoding="UTF-8"?>
    <!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://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
        <h:head>
            <title>Sistema Carros</title>
        </h:head>
        <h:body>
        
        </h:body>
    </html>
    
    

    E coloque essa estrutura nele:

    
    <h1>Sistema Carros</h1>
    <hr/>
    <ui:insert name="corpo">
    
    </ui:insert>
    
    

    E no index, podemos suprimir o head e o body, chamando ele apenas com o atributo template dentro de tags decorate, assim:

    
    <?xml version='1.0' encoding='UTF-8'?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <ui:decorate xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:f="http://xmlns.jcp.cor/jsf/core" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" template="templates.xhtml">
        
    </ui:decorate>
    
    

    Dessa forma, ele usará apenas o XML para as páginas, nada de HTML, mas para aparecer conteúdo, devemos colocar mais elementos na página index, no caso, o define, com o mesmo name do insert do template, dessa forma:

    
    <ui:define name="corpo">
        <h1>Bem-vindo ao Sistema</h1>
    </ui:define>
    
    

    Podemos ter mais de um insert no template, desde que tenham nomes diferentes.

    Mas também podemos usar insert sem names no template, e usar um span no index, sem as tags define, assim:

    
    <h1>Bem-vindo ao Sistema</h1>
    <span>Sistema</span>
    
    

    No template, podemos criar um menu assim (abaixo do h1 com Sistema Carros):

    
    <h:form>
        <p:menubar>
            <p:menuitem value="Home" url="index.jsf"></p:menuitem>
            <p:menuitem value="Gerenciar" url="gerenciar-carros.jsf"></p:menuitem>
        </p:menubar>
    </h:form>
    
    

    Todas as páginas aplicadas, terão os elemento aplicados nas páginas jsf, para aplicar em todas, basta usar as tags ui:decorate.

    Banco de Dados - Parte 1

    Para adicionar o banco de dados ao nosso projeto, vá em bibliotecas e adicione a biblioteca do Driver de MySQL (ou do banco que será usado, como o PostgreSQL). O do PostgreSQL pode ser baixado daqui: https://jdbc.postgresql.org/download/

    No SQL, crie o banco e a tabela com esses comandos:

    
    create database sistema_carros
    default character set utf8
    default collate utf8_general_ci;
    
    use sistema_carros;
    
    create table carro (
        id int not null auto_increment,
        modelo varchar(50) not null,
        fabricante varchar(20) not null,
        cor varchar(20) not null,
        ano date,
        primary key(id)
    )
    default charset = utf8;
    
    

    Vamos voltar ao nosso projeto de carros, com o mesmo formulário anterior.

    Crie uma nova classe (num novo pacote denominado util), chamada FabricaConexao, com esse código:

    
    package util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    public class FabricaConexao {
        private static Connection conexao; // Importe
        private static final String URL_CONEXAO = "jdbc:mysql://localhost:3306/sistema_carros"; // Se for postgre é jdbc:postgresql://localhost:5432/sistema_carros
        private static final String USUARIO = "root";
        private static final String SENHA = ""; 
    
        public static Connection getConexao() {
            if(conexao == null) {
                try {
                    Class.forName("com.mysql.jdbc.Driver"); // Se for Postgre, coloque org.postgresql.Driver
                    conexao = DriverManager.getConnection(URL_CONEXAO, USUARIO, SENHA); // Importe
                }
                catch(SQLException | ClassNotFoundException ex) { // Importe
                    Logger.getLogger(FabricaConexao.class.getName()).log(Level.SEVERE, null, ex);
                }   
            }
            return conexao;
        }
          
        public static void fecharConexao() {
            if(conexao != null) {
                try {
                    conexao.close();
                    conexao = null;
                }
                catch(SQLException ex) {
                    Logger.getLogger(FabricaConexao.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    
    

    E crie um pacote com o nome DAO e uma classe com o nome CarroDAO, dessa forma:

    
    package dao;
    
    import classes.Carro;
    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Calendar;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import util.FabricaConexao;
    
    public class CarroDAO {
        private Connection conexao = null;
    
        public CarroDAO() {
            conexao = FabricaConexao.getConexao();
        }
    
        public void salvar(Carro car) {
            String sql = "insert into carro (modelo, fabricante, cor, ano) values (?, ?, ?, ?)";
    
            try {
                PreparedStatement ps = conexao.prepareStatement(sql);
                
                Calendar ano = Calendar.getInstance(); // Importar
                ano.set(Integer.parseInt(car.getAno()), 0, 1);
                
                ps.setString(1, car.getModelo());
                ps.setString(2, car.getFabricante());
                ps.setString(3, car.getCor());
                ps.setDate(4, new Date(ano.getTimeInMillis())); // Importe Java.sql.Date
                
                ps.execute();
                
                FabricaConexao.fecharConexao();
            }
            catch(SQLException ex) {
                Logger.getLogger(CarroDAO.class.getName()).log(Level.SEVERE, null, ex);
            }  
        }
    }
    
    

    PS: Note que não precisamos usar new para criar o objeto conexao, por causa do static na outra classe. Não é necessário recebermos um retorno, por isso usamos o execute() ao invés do executeQuery(), nesse caso.

    Volte na classe CarroBean e adicione a chamada da classe CarroDAO, assim:

    
    public void adicionar() {
        carros.add(car);
        new CarroDAO().salvar(car); // Importe
        car = new Carro();
    }
    
    

    Dessa forma, tudo que colocarmos no nosso formulário já será salvo, sem precisar alterar o XHTML.

    Banco de Dados - Parte 2

    Primeiramente, vamos em Carro e adicione os métodos equals e hashcode, clicando com o botão direito.

    Depois, volte em CarroDAO e coloque esse método:

    
    public List<Carro> buscar() { // Importe
        String sql = "select * from carro";
    
        try {
            PreparedStatement ps = conexao.prepareStatement(sql);
            ResultSet results = ps.executeQuery(); // Importe
            List<Carro> carros = new ArrayList<>(); // Importe
    
            while(results.next()) {
                Carro car = new Carro();
    
                Calendar ano = Calendar.getInstance();
                ano.setTime(results.getDate("ano"));
    
                car.setId(results.getInt("id")); // Isso pega o valor da coluna id da tabela.
                car.setModelo(results.getString("modelo"));
                car.setFabricante(results.getString("fabricante"));
                car.setCor(results.getString("cor"));
                car.setAno(String.valueOf(ano.get(Calendar.YEAR)));
    
                carros.add(car);
            }
            return carros;
        }
        catch(SQLException ex) {
            Logger.getLogger(CarroDAO.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
    
    

    E na Carro Bean, adicione o método listar e faça algumas alterações:

    
    private Carro car = new Carro();
    private List<Carro> carros = new ArrayList<>();
    private CarroDAO carD = new CarroDAO(); // Colocamos o objeto fora dos métodos pra não ter que criarmos ele toda hora
    
    public void adicionar() {
        carros.add(car);
        carD.salvar(car);
        car = new Carro();
    }
    
    public void listar() {
        carros = carD.buscar();
    }
    
    

    E no xhtml, coloque esse botão, ao lado do adicionar:

    
    <p:commandButton value="Buscar" action="#{carroBean.listar()}" update="@form"></p:commandButton>
    
    

    Volte em CarroBean e coloque esse método:

    
    public void editar(Carro c) {
        car = c;
    }
    
    

    E no XHTML, dentro da tag dataTable, como o primeiro elemento dele, essas tags:

    
    <p:column>
        <p:commandButton value="Editar" action="#{carroBean.editar(carroForm)}" update="@form"></p:commandButton>
    </p:column>
    
    

    E no CarroDAO, altere o método salvar dessa forma:

    
    public void salvar(Carro car) {
        String sql;
    
        try {
            PreparedStatement ps;
    
            if(car.getId() == null) {
                sql = "insert into carro (modelo, fabricante, cor, ano) values (?, ?, ?, ?)";
    
                ps = conexao.prepareStatement(sql);
            }
            else {
                sql = "update carro set modelo = ?, fabricante = ?, cor = ?, ano = ? where id = ?";
    
                ps = conexao.prepareStatement(sql);
                ps.setInt(5, car.getId());
            }
            
            Calendar ano = Calendar.getInstance(); // Importar
            ano.set(Integer.parseInt(car.getAno()), 0, 1);
    
            ps.setString(1, car.getModelo());
            ps.setString(2, car.getFabricante());
            ps.setString(3, car.getCor());
            ps.setDate(4, new Date(ano.getTimeInMillis())); // Importe Java.sql.Date
            ps.execute();
    
            FabricaConexao.fecharConexao();
        }
        catch(SQLException ex) {
            Logger.getLogger(CarroDAO.class.getName()).log(Level.SEVERE, null, ex);
        }  
    }
    
    

    Em CarroBean, exclua o método carros.add(car) em adicionar, para não causar confusão na visualização, já que este não interfere no banco do nosso site.

    Podemos mudar também o value do button Adicionar para Adicionar/Atualizar.