quarta-feira, 15 de junho de 2016

Aplicação web com JSF+HIBERNATE+PRIMEFACES

Anteriormente vimos como implementar uma Aplicação web com JSF+JDBC+PRIMEFACES utilizando MER (Modelo Entidade Relacionamento), onde as tabelas são modeladas, e em seguida devem ser mapeadas. No post de hoje será utilizado Hibernate para desenvolver o mesmo exemplo. Hibernate utiliza ORM (Modelo Objeto Relacionamento), aqui os objetos são mapeados e as tabelas geradas automaticamente utilizando o mapeamento como referencia:

  • JSF (Java Serve Faces) : framework MVC de aplicações web baseado em Java. 
  • Prime Faces: Biblioteca de componentes ricos para JSF. 
  • Hibernate: O Hibernate é um framework para o mapeamento objeto-relacional escrito na linguagem Java 
  • JPA: Java Persistence API (ou simplesmente JPA) é uma API padrão da linguagem Java que descreve uma interface comum para frameworks de persistência de dados.

1. Requisitos.




2. Criando projeto.

1.Arquivo > novo projeto > java web > aplicação web > próximo
2.Escreva o nome da aplicação (no meu caso agenda) > próximo
3.Selecionado o servidor de aplicação de sua preferencia (tomcat no meu caso) e java EE deixe a versão default > próximo

4.Selecione o framework JSF e deixe as configurações default > clique em finalizar



3. Estrutura de pacotes do projeto

Crie os pacotes
  • DAO 
  • modelo 
  • hibernate 
  • controle
4. Adicionando os JAR's a biblioteca

Adicione os JAR's:
  • primefaces-versão.jar
  • all-themes-versão.jar

  • Adicione a biblioteca JDBC postgresSQL

...se você chegou até aqui a estrutura do projeto deve estar assim:

5. Incluindo cabeçalho

Abra a pagina index.xhtml gerada automaticamente na criação do projeto, e faça a inclusão do cabeçalho do primefaces.   xmlns:p="http://primefaces.org/ui"

Feito isso você esta apto a fazer uso de qualquer componente do primefaces, para o uso dos componentes a sintaxe é semelhante a sintaxe padrão dos componentes do JSF, a diferença é que em vez da letra "h" utilizaremos "p". Ex:
No site do primefaces, existe diversos exemplos em código, para todos os componentes, vale a pena conferir:  http://www.primefaces.org/showcase/ 

6. Setando o tema utilizado

Com o prime existe ainda a possibilidade de utilizar diversos outros temas, para utilizar qualquer tema, basta ter o jar com todos os temas(all-themes-versão.jar) adicionado ao seu projeto, e adicionar o seguinte código no arquivo web.xml dentro de WEB-INF.

 <context-param>   
     <param-name>primefaces.THEME</param-name>   
     <param-value>start</param-value>   
   </context-param>  

No caso start é o tema que estou utilizando. O nome dos temas estão no endereço em comunity:


7. Criando banco (postgres)

Primeiro crie um novo banco de dados no SGBD, nome "exJSF", dono "postgres" e o resto deixe default.



8. Criando classes


No pacote modelo criaremos uma classe:
  1. ContatosModelo
Essa classe deve  ser mapeada da forma que queremos que seja a estrutura da tabela no banco, os atributos devem estar encapsulados.


package modelo;

import DAO.ContatoDAO;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 *
 * @author filipe.damasceno
 */
@Entity(name="contatos")
public class ContatoModelo {
    @Id
    @GeneratedValue
    private int id;
    private String nome;
    private String telefone;

    public void save(){
        ContatoDAO.getInstance().save(this);
    }
    public void delete(){
        ContatoDAO.getInstance().delete(this);
    }
    public void update(){
        ContatoDAO.getInstance().update(this);
    }
    public static List<ContatoModelo> selectAll(){
        return ContatoDAO.getInstance().selectAll();
    }
    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return the nome
     */
    public String getNome() {
        return nome;
    }

    /**
     * @param nome the nome to set
     */
    public void setNome(String nome) {
        this.nome = nome;
    }

    /**
     * @return the telefone
     */
    public String getTelefone() {
        return telefone;
    }

    /**
     * @param telefone the telefone to set
     */
    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }
}

No pacote hibernate, crie um arquivo de configuração:


 > Próximo


Selecione o pacote > Próximo



 Crie uma nova conexão com o banco criado no postgres


 Selecione o driver PostegreSQL


Preencha os dados e Teste a conexão, se tudo estiver ok > próximo


Selecione o esquema, e clique em finalizar


...Ao clicar em finalizar, as bibliotecas necessárias para o funcionamento do hibernate são adicionadas automaticamente se você chegou até aqui a estrutura do projeto deve estar assim:

Abra o arquivo hibertate.cfg.xml e clique em código fonte. Adicione o código abaixo:

<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="modelo.ContatoModelo"/>

O arquivo ficará assim:





No pacote DAO criaremos a classe:
  1. ContatosDAO
A classe ContatosDAO.java, contem as operações de CRUD(Create, Read, Update, Delete):
  1. Save: recebe um objeto ContatosModelo.java como parâmetro, e faz a inserção no banco através do hibernate;
  2. delete: recebe um objeto ContatosModelo.java como parâmetro, e faz a deleção no banco através do hibernate;
  3. selectALL: seleciona todos os dados da tabela e retorna um alista de contatoModelo;

package DAO;

import hibernate.HibernateUtil;
import java.util.List;
import modelo.ContatoModelo;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 *
 * @author filipe.damasceno
 */
public class ContatoDAO {
    private static final ContatoDAO singleton = new ContatoDAO();
    
    public static ContatoDAO getInstance(){
        return singleton;
    }
    
    public void save(ContatoModelo c){
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        session.save(c);
        t.commit();
    }
    public void delete(ContatoModelo c){
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        session.delete(c);
        t.commit();
    }
    public void update(ContatoModelo c){
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        session.update(c);
        t.commit();
    }
    public List<ContatoModelo> selectAll(){
        List<ContatoModelo> lista = null;
        
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        lista = (List<ContatoModelo>)session.createQuery("from modelo.ContatoModelo").list();
        t.commit();
        
        return lista;
    }
}


No pacote controle criaremos uma classe:
  1. ContatosControle
Essa classe irá se comunicar com nossa pagina xHTML (view), essa será a única classe visível a partir da view, e ela é responsável por controlar as interações. Possui dois atributos do tipo ContatosModelo e os dois devem estar encapsulados, é importante ter os Geteres e Seteres, se não o framework JSF não funcionará corretamente.  Os 4 métodos da classe de controle são:

  1.  insert: Valida o dado a ser inserido e se tudo estiver correto faz a inserção
  2. delete: Valida o dado a ser inserido e se tudo estiver correto faz a deleção
  3. selectALL: retorna uma lista com todos os contatos;
  4. cadastroValido: verifica se os dados estão ok;

Depois de criar a classe é necessário colocar duas anotações, uma para informar que essa classe será no ManagedBean (controle), e outra para informar o escopo (request), RequestScoped fará a classe ser instanciada a cada requisição de usuário. 

@ManagedBean
@RequestScoped



package controle;

import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import modelo.ContatoModelo;
import org.primefaces.context.RequestContext;

/**
 *
 * @author filipe.damasceno
 */
@ManagedBean
@ViewScoped
public class ContatosControle {

    private ContatoModelo contato;
    private ContatoModelo contatoSelecionado;

    public ContatosControle() {
        contato = new ContatoModelo();
    }

    public boolean cadastroValido() {
        if (!contato.getNome().equals("")) {
            if (!contato.getTelefone().equals("")) {
                return true;
            } else {
                FacesContext.getCurrentInstance().addMessage("msg", new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro!", "Digite o telefone"));
                RequestContext.getCurrentInstance().execute("camposObrigatorios()");
                return false;
            }
        } else {
            FacesContext.getCurrentInstance().addMessage("msg", new FacesMessage(FacesMessage.SEVERITY_INFO, "Erro!", "Digite o nome"));
            RequestContext.getCurrentInstance().execute("camposObrigatorios()");
            return false;
        }
    }

    public void insert() {
        if (cadastroValido()) {
            contato.save();
            RequestContext.getCurrentInstance().execute("PF('cadastro').hide()");
        }
    }

    public void delete() {
        if (contatoSelecionado != null) {
            contatoSelecionado.delete();
            FacesContext.getCurrentInstance().addMessage("msg", new FacesMessage(FacesMessage.SEVERITY_INFO, "Contato exluido", ""));
        } else {
            FacesContext.getCurrentInstance().addMessage("msg", new FacesMessage(FacesMessage.SEVERITY_INFO, "Selecione algum contato", ""));
        }

        RequestContext.getCurrentInstance().execute("PF('deleta').hide()");
    }

    public List<ContatoModelo> selectAll() {
        return ContatoModelo.selectAll();
    }

    public ContatoModelo getContato() {
        return contato;
    }

    public void setContato(ContatoModelo contato) {
        this.contato = contato;
    }

    public ContatoModelo getContatoSelecionado() {
        return contatoSelecionado;
    }

    public void setContatoSelecionado(ContatoModelo contatoSelecionado) {
        this.contatoSelecionado = contatoSelecionado;
    }

}

9. Criando a VIEW.
Nossa tela inicial ficará assim:
Ela possui um datatable, três commandButton um fieldset e três dialog:
Código da pagina index:



<?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:p="http://primefaces.org/ui">
    <h:head>
        <title>Agenda</title>
    </h:head>
    <h:body>  
        <!--=======================================================================================================================   
          TODAS AS MENSAGENS EXIBIDAS NA TELA  
          SERÃO EXIBIDAS UTILIZANDO ESSE COMPONENTE growl,   
          QUE EH CHAMADO PELO ID E REFERENCIADO DE DENTRO DO BEAN PELO for  
        ===========================================================================================================================-->        
        <p:growl id="menssagem" showDetail="true" life="3000" for="msg"/> 
        <br/><br/><br/>        
        <p:fieldset legend="AGENDA" toggleable="true" toggleSpeed="500">          
            <h:form id="form">                
                <center>  
                    <p:dataTable id="tabela" var="item" value="#{contatosControle.selectAll()}" rowKey="#{item.id}" selectionMode="single"    
                                 scrollable="true" scrollHeight="300" scrollWidth="850" selection="#{contatosControle.contatoSelecionado}">  
                        <p:column headerText="Nome" width="100">  
                            <h:outputText value="#{item.nome}"></h:outputText>  
                        </p:column>   
                        <p:column headerText="Telefone" width="100">  
                            <h:outputText value="#{item.telefone}"></h:outputText>  
                        </p:column>  
                    </p:dataTable>  
                </center>   
            </h:form>   
            <center>  
                <p:commandButton value="Cadastrar" icon="ui-icon-document" update=":form2:displayCadastro" oncomplete="PF('cadastro').show();"/>   
                <p:commandButton value="Vizualizar" icon="ui-icon-search" oncomplete="PF('visualiza').show();" update=":displayVisualiza"/>   
                <p:commandButton value="Deletar" icon="ui-icon-disk" oncomplete="PF('deleta').show();" update=":displaydeleta"/>  
            </center>              
        </p:fieldset>  
        <!--CADASTRO DE CONTATO-->             
        <p:dialog id="dialogCadastro" header="Cadastrar contato" widgetVar="cadastro" resizable="false" width="300" showEffect="clip" hideEffect="explode">   
            <h:form id="form2">  
                <h:panelGrid id="displayCadastro" columns="2" cellpadding="4">   
                    <h:outputText value="*Nome:" />    
                    <br/>  
                    <p:inputText value="#{contatosControle.contato.nome}" />   
                    <br/>  
                    <h:outputText value="*Telefone:" />   
                    <br/>  
                    <p:inputMask value="#{contatosControle.contato.telefone}" mask="(99)9999-9999"/>  
                    <br/>                      
                    <p:commandButton value="Cadastrar" icon="ui-icon-search" action="#{contatosControle.insert()}" update=":form:tabela,:menssagem"/>   
                </h:panelGrid>   
            </h:form>  
        </p:dialog> 
        <!--VISUALIZAÇÃO DE CONTATO-->             
        <p:dialog id="dialogVisualiza" header="Vizualizar contato" widgetVar="visualiza" resizable="false" width="400" showEffect="clip" hideEffect="fold">   
            <h:panelGrid id="displayVisualiza" columns="2" cellpadding="4">   
                <h:outputText value="Nome:" />   
                <h:outputText value="#{contatosControle.contatoSelecionado.nome}" />   
                <h:outputText value="Telefone:" />   
                <h:outputText value="#{contatosControle.contatoSelecionado.telefone}" />           
            </h:panelGrid>  
        </p:dialog>    
        <!--DELEÇÂO DE CONTATO-->        
        <p:dialog id="dialogDeleta" header="Vizualizar contato" widgetVar="deleta"  width="400" showEffect="clip" hideEffect="fold">   
            <h:panelGrid id="displaydeleta" columns="2" cellpadding="4">   
                <h:outputText value="Deseja exluir realmente o contato?" />  
                <br/>  
                <p:commandButton value="Sim" action="#{contatosControle.delete()}" update=":form:tabela,:menssagem"/>   
                <p:commandButton value="Não" oncomplete="deleta.hide()" update=":form:tabela,:menssagem"/>   
            </h:panelGrid>  
        </p:dialog> 
        <script type="text/javascript">
            function camposObrigatorios() {
                jQuery('#form2').effect("shake", {times: 3}, 100);
            }
        </script>  
    </h:body>
</html>


                                             Download do projeto no github

Nenhum comentário:

Postar um comentário

Deixe um comentário!