21 de junho de 2007

Tutorial JSF - Parte 1

Bom Vamos começar, desculpe a demora, na verdade vou atualizar se der toda semana, faculdade, provas e etc me atrapalham um pouco.

Bom não vou entrar em detalhe sobre Hibernate, no Blog do Alberto ele está detalhando muito bem isso.

A idéia será focar melhor em JavaServer Faces.




Bom, vamos imaginar algo bem simples de fazer, uma agenda Web, no qual o propósito será:

Incluir, Excluir e Alterar meus contatos.

Poderíamos ter feito de várias maneiras, por exemplo, JDBC puro, Struts, Spring, Struts 2, e etc.




Mas por que JSF e JPA? Porque são padrões da SUN e está documentado em JSR´s, sem perigo de por exemplo: "O grupo que desenvolvia o framework XPTO não faz mais, perdi tudo e vamos ter que migrar".




O que vamos precisar para esse primeiro exemplo?

Baixe o JDK do site da Sun.

Baixe o EasyEclipse ou o IDE que você goste mais.

Baixe o webcontainer, o TomCat é muito bom para esse pequeno exemplo.

Baixe o MyFaces Tomahawk.
Baixe o Hibernate: - Hibernate Core, Hibernate Annotations e o Hibernate EntityManager.

Baixe o MySQL.

Descompacte os arquivos no seu ClassPath do projeto e vamos começar.




Como utilizaremos Hibernate e JPA não precisamos gerar as tabelas na mão dentro do Banco, vamos montar um esquema com anotações que o Hibernate crie.




XML

Vamos começar com o hibernate.cfg.xml



















Básicamente ninguém cria do zero isso, normalmente todo mundo tem esse padrão +/- aí de cima, vou detalhar um pouco do q cada linha faz para ficar bem claro.

property name="hibernate.dialect"
org.hibernate.dialect.MySQLDialect

property name="hibernate.connection.url"

jdbc:mysql://localhost/teste

property name="hibernate.connection.driver_class"
com.mysql.jdbc.Driver

property name="hibernate.connection.username"
root

property name="hibernate.connection.password"
root

Essas linhas servem para:

-Dizer qual o meu banco de dado, caso mude é só alterar o Dialect.

- A String de conexão e url

- O Meu usuário e senha do Banco




property name="hibernate.c3p0.min_size" 1 /property
property name="hibernate.c3p0.max_size" 10 /property
property name="hibernate.c3p0.maxIdleTime" 200 /property
property name="hibernate.c3p0.timeout" 180 /property
property name="hibernate.c3p0.idle_test_period" 100 /property
property name="hibernate.c3p0.max-statements" 50 /property




Para meu Pool de conexões, ou seja, para delimitar alguns limites estou usando o C3PO que já está nos Jar´s do Hibernate.

Estou usando Cache level 2 para manter alguns objetos em chache (não era preciso), é algo bem legal que o Hibernate possui.







mapping class="br.com.caelum.acesso.Acesso"/
mapping class="br.com.caelum.dados.Dados"/
mapping class="br.com.caelum.fornecedor.Fornecedor"/
mapping class="br.com.caelum.contapagar.ContaPagar"/

Aqui estou mapeando as minhas classes que serão entidades no Banco.







CLASSES




Para nosso sistema, devemos criar uma tela de Login e senha antes de entrar na Agenda, isto por mera segurança, você não quer que seu "irmão pentelho" fique mexendo nos seus contatos, quer?

// Login e acesso ao sistema

package br.com.imes.acesso;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.Session;

import br.com.imes.acessodao.AcessoDAO;
import br.com.imes.hibernate.hibernateutil.HibernateUtil;

/**
* @author Eduardo Bregaida
*
*/

@Entity
public class Acesso {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;

private String login;

private String senha;

private boolean administrador;

public boolean isAdministrador() {
return administrador;
}

public void setAdministrador(boolean administrador) {
this.administrador = administrador;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getSenha() {
return senha;
}

public void setSenha(String senha) {
this.senha = senha;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String logar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
return acessoDAO.verificaAutenticacao(this);
}

public void salvar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.salvaUsuario(this);
}

public void deletar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.excluiUsuario(this);
}


}

Para que conhecer Hibernate e/ ou JPA sabe muito bem que tem muitas anotações bem legais, vou explicar as da classe Acesso:

@Entity: aqui estou dizendo, olha sou uma entidade do Banco, vou gerar as tabelas.

@Id : o id é OBRIGATÓRIO quando você diz que uma classes é Entity

@GeneratedValue(strategy = GenerationType.IDENTITY): esta anotação é para dizer que o campo Id é auto-numeração do seu Banco de Dados.







Basicamente até aqui nada mais era do que pura JPA, mas porque então o Hibernate?
@Entity
public class Acesso {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;

private String login;

private String senha;

private boolean administrador;

public boolean isAdministrador() {
return administrador;
}

public void setAdministrador(boolean administrador) {
this.administrador = administrador;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getSenha() {
return senha;
}

public void setSenha(String senha) {
this.senha = senha;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}
}







Porque eu utilizo uma Sessão e alguns tipos de pesquisa que só o Hibernate possui, tais como: Critéria e HQL.



public String logar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
return acessoDAO.verificaAutenticacao(this);
}

public void salvar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.salvaUsuario(this);
}

public void deletar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.excluiUsuario(this);
}







Vamos ver a classe AcessoDAO para entender aqueles metodos da minha classe de Beans acesso:


package br.com.imes.acessodao;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;

import br.com.imes.acesso.Acesso;

public class AcessoDAO {

private Session session;

private Logger logger = Logger.getLogger(Acesso.class);

public AcessoDAO(Session session) {
logger.info("Construtor" + session);
this.session = session;

}

/**
* @verifica se o usuário está autorizado para logar no sistema
*/
@SuppressWarnings("unchecked")
public String verificaAutenticacao(Acesso acesso) {
logger.info("HQL" + acesso.getLogin());

Query query = session
.createQuery("select acesso from Acesso as acesso where acesso.login = :login and acesso.senha = :senha");
query.setParameter("senha", acesso.getSenha());
query.setParameter("login", acesso.getLogin());

Acesso acesso2 = (Acesso) query.uniqueResult();

if (acesso2 == null) {
return "erro";
} else {
/*if (acesso2.isAdministrador()){
return "administrador";
}else*/
return "usuario";
}

}

/**
* @verifica salva um novo usuário no sistema
*/
public void salvaUsuario(Acesso acesso) {
session.saveOrUpdate(acesso);
}

/**
* @verifica exclui um usuário no sistema
*/
public void excluiUsuario(Acesso acesso) {
session.delete(acesso);
}


@SuppressWarnings("unchecked")

public Acesso selecionaUsuario(Acesso acesso) {
// TODO Auto-generated method stub
return (Acesso) session.load(Acesso.class, acesso.getLogin());
}
}




Estes são meus métodos no DAO, nada mais são do que métodos de pesquisa, exclusão, alteração, inclusão e etc.




São tratados na minha SessionFilter no qual eu trato todos meus objetos em Sessão, para abrir a sessão foi criado um HibernateUtil onde eu também declaro minhas anotações e crio a minha sessionFactory:




HibernateUtil



package br.com.imes.hibernate.hibernateutil;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
* @author Eduardo Bregaida
*
*/
public class HibernateUtil {
private static ThreadLocal sessions;

private static SessionFactory sessionFactory;
static {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
sessions= new ThreadLocal();
}

public static Session openSession() {
return sessionFactory.openSession();
}

public static Session getCurrentSession() {
if (sessions.get() == null) {
sessions.set(openSession());
}
return sessions.get();
}

public static void closeCurrentSession() {
getCurrentSession().close();
sessions.set(null);
}
}

HibernateSessionFilter


package br.com.imes.hibernate.sessionfilter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import br.com.imes.hibernate.hibernateutil.HibernateUtil;

/**
* @author Eduardo Bregaida
*
*/
public class HibernateSessionFilter implements Filter {
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain) throws ServletException {
try {
HibernateUtil.getCurrentSession().beginTransaction();//é obrigado estar
filterChain.doFilter(servletRequest, servletResponse);
HibernateUtil.getCurrentSession().getTransaction().commit();
} catch (Exception e) {
HibernateUtil.getCurrentSession().getTransaction().rollback();
throw new ServletException(e);
} finally {
HibernateUtil.closeCurrentSession();
}

}

public void destroy() {
// TODO Auto-generated method stub

}

public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub

}
}

Aqui na HibernateSessionFilter exatamente eu fecho a transação e dou um commit ou rollback nos dados, também fecho a Sessão atual.

Existem muitas implementações para a configurar a sessionFactory, eu gosto particularmente deste pois é muito fácil de ver o que ela esta fazendo e aonde.

Mostrada a sessionFactory e a sessionFilter vamos para os DAO´s:

Este é a primeira parte do sisteminha, vamos ver se consigo mostrar como ligo isso na camada visual e vamos criar também a área de Dados do nosso sistema onde ocorrerá os cadastros de nossa agenda.

Até logo...

14 comentários:

Tiago disse...

Olá, valeu pela força em criar o tutorial.
eu gostaria de dar uma crítica construtiva, acredito que para quem tá iniciando em JEE o tutorial fica meio vago, não específica em que parte do projeto inserir as classes e como elas vão trabalhar juntas... comecei a acompanhar o projeto fazendo tudo certo, mas da metade em diante não deu p/ prosseguir... mas valeu.

Eduardo Bregaida disse...

Opa neste ano de 2008 estaremos colocando mais tutoriais passo a passo, qualquer dúvida pode me mandar por e-mail, sem problemas, a idéia era o pessoal fazer o download do projeto, mas infelizmente estou sem uma área para deixar os projetos, este ano vou comprar um domínio para isso, enquanto isso, estou enviando por e-mail o projeto para seguir com o tutorial.
Obrigado pela opinião.

22-Gers disse...

Ola Eduardo. Seu tutorial está muito bom. Realmente é difícil achar material de boa qualidade na internet. Estou começando a estudar JSF e estou ralando pra achar explicações boas para alguns conceitos.

Se vc pude me mandar os arquivos desse projeto seria uma mão na roda.

aguardo

atenciosamente


email: lsp_prado@yahoo.com.br

João Paulo disse...

Primeiro parabens pela iniciativa.
Eduardo esse é exatamente o tema de minha monografia (jsf+hibernate)
Me interesso muito pelo material, pois gostaria de dar uma estuda bem detalhada nele...

Seria muiiiito util para mim, se puder me mandar por email agradeceria muito.

joaopaulolobo@gmail.com

Chacon disse...

Caro Eduardo Bregaida
se fosse possível,você poderia mandar este projeto, pois estou com um seminário para apresentar sobre JSF e estou começando praticamente do zero, esse seu tutorial seria uma mão na roda

pode mandar para o e-mail
charles.chacon.cg@gmail.com

mawerc disse...

Saudações:

Como a maioria das pessoas também estou começando com JSF+Hibernate e o seu tutorial é muito bom para isso, quanto ao espaço para disponibilizar seus tutoriais, posso ceder-lhe um espaço em meu dominio para já.
Podemos tratar do assunto a partir do e-mail abaixo

mawerc@gmail.com

também quero receber o tutorial.

Eduardo Bregaida disse...

Opa para esse tutorial deixei o link de onde está hospedado na parte 2, porém, vamos sim conversar por e-mail para deixar os futuros, muito obrigado.

clakrall disse...

Gostaria de estar recebendo o material (claudio@mileniumtech.com.br). Valeu pela iniciativa...

Eduardo Bregaida disse...

Opa na parte 2 do Blog tem o download
=)
Abraços

Rodrigo Fernandes disse...

Um dominio .com e .net é so mente 5,90 muito barato....

qualquer duvida rodrigo@log7.net


www.ganharnaloteria.log7.net

Luís Antonio disse...

Olá,

Muito bom, poderia me mandar tb por email?

poti158@yahoo.com.br

Vlw ;>)

Anônimo disse...

Eduardo,
Bom dia,
Sou desenvolvedor em .net e agora vou aprender a trabalhar com o mundo Java, sou que sinceramente estou bem perdido e por tal peço uma dica da sua parte de por onde começar.
1 - Para trabalhar com Java o ideal seria aprender:
1.1 - JSP - paginas dinamicas.
1.2 - JSTL - Interação com JSP.
1.3 - Servelets, para criação de uma ponte entre a base de dados e as páginas dinamicas.
1.4 - JDBC - Acesso ao Banco de Dados.

Seria esses passos a serem adotados e uma outra coisa, voce saberia indicar algum livro bom, para dar inicio aos estudos nesta plataforma.
meu nome é José Paulo, e não tenho conta do Google

Eduardo Bregaida disse...

Correto aconselho começar por esse: http://oreilly.com/catalog/9780596516680
Depois veja os frameworks mais comuns, Struts, JSF, JBoss Seam e Hibernate.
=)
[]s

David Cortez disse...

Cara muito bom esse tuto direto simples e objetivo, estou começando nesse mundo de blogueiro esse seu blog é um ótimo exemplo
http://noobjava.wordpress.com