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...

19 de junho de 2007

Primeiro Exemplo

Pessoal, vou postar passo a passo como desenvolver de modo prático e fácil uma aplicação utilizando Hibernate e JPA, JavaServer Faces e Ajax.
Vai ser um tutorial bem básico, na verdade trata-se de uma agenda, onde o usuário loga no sistema, cadastra novos usuários para a agenda.
Este projeto foi desenvolvido para uma pequena transportadora, por ser um projeto simples, fica bem legal e fácil para entender.
Vou ver se nessa semana (Está meio difícil) mas eu já começo a postar a primeira parte que nada mais será do que:
Modelo de Dados, escolha do Banco, Analise de Requisitos, Volume dos dados e montar esta primeira parte utilizando Hibernate e JPA.
A Segunda fase será a implementação do JavaServer Faces.
Para Finalizar utilizaremos Ajax, para auto-completar a nossa pesquisa.

Abertura Oficial

Bom, depois de muito relutar (motivo de tempo), atendi a pedidos do meu amigo Michael do Nascimento (Mister M) e estou reabrindo meu Blog.

Pretendo colocar alguns artigos e comentar alguns erros que vejo durante as horas e horas de desenvolvimento, assim como Assuntos interessantes, palestras, eventos e tudo mais que for possível.

Espero que consiga arrumar tudo direitinho.