DAO Genérico

21 respostas
ricardocomp

Olá pessoal gostaria de saber a opinão de todos sobre o meu DAO genérico
gostaria de saber se é preciso melhorar alguma coisa.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.icmc.usp.dao;
  
import br.icmc.usp.excecoes.ExcecaoDAO;
import br.icmc.usp.util.JPAUtil;
import java.util.List;
import javax.persistence.EntityTransaction;
import javax.persistence.EntityManager;
import javax.persistence.Query;

/**
 * Classe utilizada para fazer realizar as operações de banco de dados
 * @author Ricardo
 */
public class DAOGenerico<T> implements InterfaceDAO<T> {               
    
    private EntityTransaction getTransacao(EntityManager session){         
        EntityTransaction transaction = session.getTransaction(); 
        return transaction;
    }
    
 /**
  * Salva o objeto no banco de dados.
  * @param object: Entidade a ser Salva (se ainda não existir) 
  * @return Retorna a Entidade passada como parâmetro.
  * @throws Exception
  */
    @Override
    public T salvar(T object) throws ExcecaoDAO {
        EntityTransaction transaction = null;         
        EntityManager session = JPAUtil.getInstance().getEntityManager();       
        try{            
            transaction = getTransacao(session);
            transaction.begin(); 
            session.persist(object);  
            transaction.commit();  
            return object;    
        }
        catch(Exception e){  
            transaction.rollback();  
            throw new ExcecaoDAO(object.getClass().getSimpleName().toString() + " :: Erro ao inserir os dados!");              
        }
        finally {
            session.close();
        }
    }

 /**
  * Retorna a lista de itens salvo no banco de dados de acordo com a Entidade passada como parâmetro.
  * @param classe : Entidade que deverá buscar no banco de dados.
  * @return List contendo todos os objetos encontrados da entidade passada como parâmetro.
  */
    public List<T> listar(Class classe) throws ExcecaoDAO {        
        EntityManager session = JPAUtil.getInstance().getEntityManager();
        try{                           
            Query query = session.createQuery("SELECT e FROM " + 
                    classe.getSimpleName().toString() + " e");
            return (List<T>) query.getResultList();            
        }
        catch(Exception e){              
            throw new ExcecaoDAO(classe.getSimpleName().toString() + 
                    " :: Erro ao listar os dados!");  
        }  
        finally {
            session.close();
        }  
    }

 /**
  * Faz a busca no banco pelo ID da entidade
  * @param classe : Entidade a ser buscada
  * @param id : valor a ser procurado
  * @return Objeto encontrado no banco, caso não encontre será retornado NULL
  * @throws Exception
  */
    @Override
    public T procurarPorId(Class classe, Integer id) throws ExcecaoDAO {                            
        EntityManager session = JPAUtil.getInstance().getEntityManager();
        T object = null;
        try{                       
            object = (T) session.find(classe, id);             
            return object;
        }
        catch(Exception e){             
            throw new ExcecaoDAO(classe.getSimpleName().toString() + 
                " :: Erro ao procurar os dados do Aluno. (O id não existe!)."); 
        }
        finally {
            session.close();
        }
    }       

    
 /**
  * Atualiza o objeto no banco de dados.
  * @param object: Entidade a ser Atualizada (se já existir)
  * @return Retorna a Entidade passada como parâmetro.
  * @throws Exception
  */
    @Override
    public T atualizar(T object) throws ExcecaoDAO {
        EntityTransaction transaction = null; 
        EntityManager session = JPAUtil.getInstance().getEntityManager();
        try{           
            transaction = getTransacao(session);
            transaction.begin();       
            session.merge(object);  
            transaction.commit();  
            return object;    
        }catch(Exception e){  
            transaction.rollback();  
            throw new ExcecaoDAO(object.getClass().getSimpleName().toString() + 
                " :: Erro ao atualizar dados!");   
        }  
        finally {
            session.close();
        }
    }

 /**
  * Remove a Entidade do banco de dados.
  * @param object: Entidade a ser removido do banco de dados.
  * @throws Exception
  */
    @Override
    public T excluir(T object) throws ExcecaoDAO {
        EntityTransaction transaction = null; 
        EntityManager session = JPAUtil.getInstance().getEntityManager();
        try{            
            transaction.begin();        
            session.remove(object);                       
            transaction.commit();  
            return object;    
        }catch(Exception e){  
            transaction.rollback();  
            throw new ExcecaoDAO(object.getClass().getSimpleName().toString() + 
                " :: Erro ao Excluir os dados!");  
        }
        finally {
            session.close();
        }
    }
    
   
}

[]'s.

21 Respostas

gabbardo

Eu acho que está ok para oq eu vejo que você está propondo no DAO. Não testei nem nada e minha opinião não é a unica. Dá uma olhada nesses links que podem ajudar:

http://community.jboss.org/wiki/GenericDataAccessObjects

lucasmurata

Amigo, sinceramente,

hoje em dia voce nem precisa mais criar suas DAOs pra sua app…Muito menos de DAO Generico que na minha opinião é coisa mais esquisita que tem :evil: .

ricardocomp

Falaaa gabbardo, vou dar uma olhada nos links q vc me passou :smiley: .

lucasmurata o q vc sugere então para o meu caso?

[]'s.

romarcio
Eu mudaria uma coisa, que facilitaria um pouco. Teoricamente você vai estender seu DAO generico nas classes de DAO's mais especificas. Então ao invés de fazer isso:
public List&lt;T&gt; listar(Class classe) throws ExcecaoDAO {...}
passar a classe de entidade por parametro, faça isso:
private final Class&lt;T&gt; persistentClass;

public DAOGenerico() {
        this.persistentClass = (Class&lt;T&gt;) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

public List&lt;T&gt; listar() throws ExcecaoDAO {          
        EntityManager session = JPAUtil.getInstance().getEntityManager();  
        try{                             
            Query query = session.createQuery("SELECT e FROM " + persistentClass.getName() + " e");  
            return (List&lt;T&gt;) query.getResultList();              
        }  
        catch(Exception e){                
            throw new ExcecaoDAO(classe.getSimpleName().toString() +   
                    " :: Erro ao listar os dados!");    
        }    
        finally {  
            session.close();  
        }    
}
Na classe de DAO especifico você vai declarar assim:
public class UsuarioDAO extends DAOGenerico&lt;Usuario&gt; {}
Dai não vai precisar passa a classe como parâmetro quando precisar.
A

alem das metodos que vc criou, eu tbm colocaria todos os tipos de consulta como generico, pois nos seus DAOs vc nao precisaria se preucupar com isso, somente com os sql’s.

t+

lucasmurata

ricardocomp:
Falaaa gabbardo, vou dar uma olhada nos links q vc me passou :smiley: .

lucasmurata o q vc sugere então para o meu caso?

[]'s.

Não tem que reinventar a roda. Pra que Generic DAO proprio? EntityManager não serve? Persiste, Merge, Find, Remove, tem tudo.

Fora que em uma aplicação, nem sempre um delete, insert ou list generico serve para todas entidades…Esquece esse lance de DAO generico ou voce vai fazer um bolo na sua app.

ricardocomp

Falaaa romarcio obrigado pela dica :D.

Eaê Alisson não entendi direito a sua dica

Teria como vc me dar um exemplo Alisson?

[]'s.

A

segue um exemplo de um dao generico que eu uso

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;

import org.hibernate.Session;

public abstract class BaseDAO<T> {
	
	@PersistenceContext
	private EntityManager entityManager;
	
	protected BaseDAO(){
	}
	
	public void inserir(T object) {
		entityManager.persist(object);
		entityManager.flush();
	}

	public T alterar(T object) {
		object = entityManager.merge(object);
		entityManager.flush();
		
		return object;
	}
	
	public void excluir(Class<T> classe, Object id) {
		entityManager.remove(entityManager.find(classe, id));
		entityManager.flush();
	}
	
	@SuppressWarnings("rawtypes")
	protected void excluirClausulaIN(String sql, HashMap<String, Object> parametros){
		Session session = (Session) entityManager.getDelegate();
		
		org.hibernate.Query query = session.createQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				if(parametros.get(parametro) instanceof List){
					query.setParameterList(parametro, (List)parametros.get(parametro));
				}else{
					query.setParameter(parametro, parametros.get(parametro));
				}
			}
		}
		
		query.executeUpdate();
	}

	public void executeNativeQuery(Class<T> classe, String sql, HashMap<String, Object> parametros) {
		Query query = entityManager.createNativeQuery(sql, classe);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				query.setParameter(parametro, parametros.get(parametro));
			}
		}
		
		query.executeUpdate();
	}
	
	public T pesquisar(Class<T> classe, Object id) {
		return (T) entityManager.find(classe, id);
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> pesquisarEntidades(String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Query query = entityManager.createQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				if(parametros.get(parametro) instanceof Date){
					query.setParameter(parametro, (Date)parametros.get(parametro), TemporalType.DATE);
				}else{
					query.setParameter(parametro, parametros.get(parametro));
				}
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.getResultList();
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected List<T> pesquisarEntidadesClausulaIN(String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Session session = (Session) entityManager.getDelegate();
		
		org.hibernate.Query query = session.createQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				if(parametros.get(parametro) instanceof List){
					query.setParameterList(parametro, (List)parametros.get(parametro));
				}else{
					query.setParameter(parametro, parametros.get(parametro));
				}
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.list();
	}
	
	protected List<T> pesquisarEntidades(String sql, HashMap<String, Object> parametros){
		return pesquisarEntidades(sql, parametros, true, 0, 0);
	}
	
	protected List<T> pesquisarEntidades(String sql){
		return pesquisarEntidades(sql, null, true, 0, 0);
	}
	
	protected List<T> pesquisarEntidadesClausulaIN(String sql, HashMap<String, Object> parametros){
		return pesquisarEntidadesClausulaIN(sql, parametros, true, 0, 0);
	}
	
	protected List<T> pesquisarEntidadesClausulaIN(String sql){
		return pesquisarEntidadesClausulaIN(sql, null, true, 0, 0);
	}
	
	@SuppressWarnings("unchecked")
	protected List<T> pesquisarEntidadesNativeQuery(Class<T> classe, String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Query query = entityManager.createNativeQuery(sql, classe);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				query.setParameter(parametro, parametros.get(parametro));
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	protected T pesquisarEntidadeNativeQuery(Class<T> classe, String sql, HashMap<String, Object> parametros){
		try {
			Query query = entityManager.createNativeQuery(sql, classe);
			
			if(parametros != null && !parametros.keySet().isEmpty()){
				for(String parametro : parametros.keySet()){
					if(parametros.get(parametro) instanceof Date){
						query.setParameter(parametro, (Date)parametros.get(parametro), TemporalType.TIMESTAMP);
					}else{
						query.setParameter(parametro, parametros.get(parametro));
					}
				}
			}
			
			return (T) query.getSingleResult();
		} catch (Exception e) {
			return null;
		}
	}
	
	
	@SuppressWarnings("unchecked")
	protected List<T> pesquisarEntidadesNativeQuery(String sql, HashMap<String, Object> parametros, boolean todos, int primeiroResultado, int maxResultado){
		Query query = entityManager.createNativeQuery(sql);
		
		if(parametros != null && !parametros.keySet().isEmpty()){
			for(String parametro : parametros.keySet()){
				query.setParameter(parametro, parametros.get(parametro));
			}
		}
		
		if (!todos) {
			query.setMaxResults(maxResultado);
			query.setFirstResult(primeiroResultado);
		}
		return query.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	protected T pesquisarEntidade(String sql, HashMap<String, Object> parametros) throws NoResultException{
		try{
			Query query = entityManager.createQuery(sql);
			
			if(!parametros.keySet().isEmpty()){
				for(String parametro : parametros.keySet()){
					if(parametros.get(parametro) instanceof Date){
						query.setParameter(parametro, (Date)parametros.get(parametro), TemporalType.TIMESTAMP);
					}else{
						query.setParameter(parametro, parametros.get(parametro));
					}
				}
			}
			
			return (T) query.getSingleResult();
		}catch(Exception e){
			return null;
		}
	}
}
public class UsuarioDAO extends BaseDAO<Usuario> {
	
	protected UsuarioDAO() {
		
	}
	
	public List<Usuario> pesquisarUsuarios(Usuario usuario){
		HashMap<String, Object> parametros = new HashMap<String, Object>();
		StringBuilder query = new StringBuilder();
		
		query.append("SELECT u ");
		query.append("FROM Usuario u ");
		query.append("	INNER JOIN FETCH u.perfilUsuario p ");
		query.append("WHERE 1 = 1 ");
		
		if(usuario != null && usuario.getNome() != null && !usuario.getNome().trim().equals("")){
			query.append("AND UPPER(u.nome) like :nome ");
			parametros.put("nome", "%"+usuario.getNome().toUpperCase()+"%");
		}
		if(usuario != null && usuario.getEmail() != null && !usuario.getEmail().trim().equals("")){
			query.append("AND UPPER(u.email) like :email ");
			parametros.put("email", "%"+usuario.getEmail().toUpperCase()+"%");
		}
		if(usuario != null && usuario.getLogin() != null && !usuario.getLogin().trim().equals("")){
			query.append("AND UPPER(u.login) like :login ");
			parametros.put("login", "%"+usuario.getLogin().toUpperCase()+"%");
		}
		query.append("ORDER BY u.nome ");
		
		return pesquisarEntidades(query.toString(), parametros);
	}
}

espero que te ajude.

t+

R

Alguns comentários:

  • Você está abrindo e fechando uma transação para cada elemento individual que grava. Como você fará para preservar o desempenho se tiver que gravar 200 elementos em seqüência?
  • Verifique se a transação é diferente de NULL antes de chamar rollback().
ricardocomp

Falaaa Alisson, vai me ajudar sim :D.

roger_rf não faço a menor idéia de como fazer o q vc falou

Como eu tenho q fazer para preservar o desempenho e gravar os 200 elementos em sequencia e se um der pau o rollack vai funcionar para todos os outros elementos já gravados? Será que teria como vc dar um exemplo roger_rf?

[]'s.

nel

ricardocomp:
Falaaa Alisson, vai me ajudar sim :D.

roger_rf não faço a menor idéia de como fazer o q vc falou

Como eu tenho q fazer para preservar o desempenho e gravar os 200 elementos em sequencia e se um der pau o rollack vai funcionar para todos os outros elementos já gravados? Será que teria como vc dar um exemplo roger_rf?

[]'s.

Uma pergunta, esse seu DAO é para um projeto WEB, não é?
Porque simplesmente não deixa que o servidor gerencie seu pool de conexão ?

CharlesAlves

Em vez de concatenar assim

Query query = session.createQuery("SELECT e FROM " +   
  classe.getSimpleName().toString() + " e");  
  return (List<T>) query.getResultList();

não seria melhor fazer assim?!

Query query = session.createQuery("SELECT e FROM ? e");
 query.setString(1, classe.getSimpleName());
 return (List<T>) query.getResultList();
R

ricardocomp:
Falaaa Alisson, vai me ajudar sim :D.

roger_rf não faço a menor idéia de como fazer o q vc falou

Como eu tenho q fazer para preservar o desempenho e gravar os 200 elementos em sequencia e se um der pau o rollack vai funcionar para todos os outros elementos já gravados? Será que teria como vc dar um exemplo roger_rf?

[]'s.

Inicie a transação, grave os objetos que precisam ser persistidos (não se esqueça de fazer um flush() na sessão de vez em quando, para não acumular muita coisa na memória), e então conclua a transação. E sim, o rollback vai funcionar para o que você gravou antes.

ricardocomp

Olá pessoal, estou em dúvidas agora no desenvolvimento da camada serviço e no controlador
será que alguém poderia me dar uma ajuda?

Estou desenvolvendo uma aplicação Web e estou pensando em fazer apenas uma camada de servico que servira como controlador para o meu sistema

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.icmc.usp.servico;

import br.icmc.usp.dao.DAOGenerico;
import br.icmc.usp.excecoes.ExcecaoDAO;
import br.icmc.usp.excecoes.ExcecaoServico;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 *
 * @author Ricardo
 */
public class ServicoGenerico<T> implements InterfaceServico<T> {
    
    //Não tenho como instânciar vai dar NULL POINTER EXCEPTION AQUI!!!
    private DAOGenerico<T> DAOGenerico;

    public T salvar(T object) throws ExcecaoServico {
        try {
             return DAOGenerico.salvar(object);
        } 
        catch (ExcecaoDAO ex) {
            throw new ExcecaoServico(object.getClass().getSimpleName().toString() + " :: Erro ao inserir os dados!");
        }
       
    }

//    public List<T> listar() throws ExcecaoServico {
//        List<T> lista = null;
//        try {
//             lista = DAOGenerico.listar();
//        } 
//        catch (ExcecaoDAO ex) {
////            throw new ExcecaoServico(persistentClass.getName() +     
////                    " :: Erro ao listar os dados!");   
//        }
//        return lista;
//    }

    public T procurarPorId(Class classe, Integer id) throws ExcecaoServico {
        T object = null;
        try {
             object = DAOGenerico.procurarPorId(classe, id);
        } catch (ExcecaoDAO ex) {
            throw new ExcecaoServico(classe.getSimpleName().toString()
                    + " :: Erro ao procurar os dados do Aluno. (O id não existe!).");
        }
        return object;
    }

    public T atualizar(T object) throws ExcecaoServico {
        try {
            return DAOGenerico.atualizar(object);
        } catch (ExcecaoDAO ex) {
            throw new ExcecaoServico(object.getClass().getSimpleName().toString()
                    + " :: Erro ao atualizar dados!");
        }
    }

    public T excluir(T object) throws ExcecaoServico {
        try {
            DAOGenerico.excluir(object);
        } catch (ExcecaoDAO ex) {
            throw new ExcecaoServico(object.getClass().getSimpleName().toString()
                    + " :: Erro ao Excluir os dados!");
        }
        return object;
    }
    
    /**
     * Método para ordenar as listas de String em ordem alfabética.
     * @param lista
     * @return 
     */
    public List<String> orderedList(List<String> lista) {

        Comparator<String> comparator = new Comparator<String>() {

            public int compare(String projectName1, String projectName2) {
                int resultado = -1;
                resultado = projectName1.compareToIgnoreCase(projectName2);
                return resultado;
            }
        };
        Collections.sort(lista, comparator);
        return lista;
    }

    public List<T> listar() throws ExcecaoServico {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
}

Será que alguém poderia me dar uma ajuda?

[]’.

von.juliano

Repare que esse serviço não faz nada além de delegar para o Dao. Um serviço é o cara que tem a inteligência para lidar com as informações. Não deve haver um serviço genérico que nada mais é do que um Dao genérico disfarçado.

ricardocomp

Falaaa von.juliano vc teria um exemplo de um serviço ou de uma classe controladora?

Será que vc von.juliano ou alguém poderia me dar uma ajuda?

[]'s.

ricardocomp

Será que alguém poderia me indicar algum livro ou alguma apostila e tutorial para me ajudar na parte dos serviços e do controlador da minha aplicação Web?

[]'s.

von.juliano

Isso é muito mais conceitual do que técnico. Dê um lida aqui, em todos os posts que escrevi eu fiz uso dessa idéia. Lembre-se que suas classes tem de ser simples e objetivas! :smiley:

von.juliano

Ah sim, leia o Domain Driven Design do Eric Evans, faz toda a diferença!

ricardocomp

Falaaa von.juliano vc tem o projeto do seu site?

Será que teria como vc me enviar por e-mail para eu dar uma olhada?

Se vc ou alguém puder me ajudar com exemplos práticos de uma aplicação web simple q faça uso do DAO, Serviço e Controlador aqui no forum ou me enviar por e-mail:

[email removido]

[]'s.

ricardocomp

Esse livro Domain Driven Design do Eric Evans eu já ouvi falar, mas preciso dar uma melhorada no meu inglês primeiro :D.

[]'s.

Criado 26 de setembro de 2011
Ultima resposta 28 de set. de 2011
Respostas 21
Participantes 9