Exemplo de DAO Genérico

Bom, no blog da Caelum a um tempo atras fizeram um POST sobre um DAO genérico, meio bizarro
Bom, eu uso um DAO genérico a algum tempo, mas o meu DAO genérico tm algumas features a mais do que o mostrado no post da caelum …

Neste exemplo eu ja deixo os metodos para fazer um query by example prontinho, usando a API de criteria do Hibernate …

bom, chega de enrolação, vamos a alguns exemplos …

primeiro, crio uma interface para este DAO …

package br.com.techoffice.site.dao;

import java.io.Serializable;
import java.util.List;

public interface TOBaseDao<T, PK extends Serializable> {
    public Class getObjectClass();
	public T save(T object);
	public T load(PK primaryKey);
    public T get(PK primaryKey);
	public List listAll();
	public List findByExample(final T example);
	public T findOneByExample(final T example);
	public List listAll(final int first,final int max);
	public int listAllPageCount();
	public List findByExample(final T example,final int first,final int max);
	public int findByExamplePageCount(final T example);
    public void update(T object);
    public void delete(T object);
    public void rebind(T object);
}

onde o método getObjectClass() deve retornar a classe de trabalho deste DAO, a mesma passada no parâmetro T quando a interface for estendida …

e a implementação desta interface, fica mais ou menos assim:

package br.com.techoffice.site.dao.impl;

import java.io.Serializable;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Example.PropertySelector;
import org.hibernate.type.Type;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import br.com.techoffice.site.dao.TOBaseDao;
import br.com.techoffice.site.dao.TODaoListener;

@Transactional(propagation = Propagation.REQUIRED, timeout = 20)
public abstract class TOBaseHibernateDao extends HibernateDaoSupport implements TOBaseDao<T, PK>, PropertySelector {
    private static final Log logger = LogFactory.getLog(TOBaseHibernateDao.class);
    private final Class objectClass;

    public TOBaseHibernateDao(final Class objectClass) {
        this.objectClass = objectClass;
    }

    @SuppressWarnings("unchecked")
    public Class getObjectClass() {
        return objectClass;
    }

    public int findByExamplePageCount(final T example) {
        final List l = findByExample(example);
        final Integer i = new Integer(l.size());
        return i.intValue();
    }

    public int listAllPageCount() {
        final List l = listAll();
        final Integer i = new Integer(l.size());
        return i.intValue();
    }

    /*
     * (non-Javadoc)
     *
     * @see br.ufrgs.hcpa.template.dao.GetNetBaseDao#findOneByExample(T)
     */
    public T findOneByExample(final T example) {
        final List res = findByExample(example, 0, 1);
        if ((res != null) && (res.size() == 1)) {
            return res.get(0);
        } else {
            return null;
        }
    }

    public T save(final T object) {
        try {
            final Session s = getSession(false);
            s.save(object);
            s.flush();
            return object;
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    public void update(final T object) {
        try {
            final Session s = getSession(false);
            s.update(object);
            s.flush();
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    public void rebind(final T object) {
        try {
            getSession(false).refresh(object);
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    public void delete(final T object) {
        try {
            getSession(false).delete(object);
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    @SuppressWarnings("unchecked")
    public T load(final PK primaryKey) {
        try {
            final Session s = getSession(false);
            final Object o = s.load(objectClass, primaryKey);
            return (T) o;
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    @SuppressWarnings("unchecked")
    public T get(final PK primaryKey) {
        try {
            final Session s = getSession(false);
            final Object o = s.load(objectClass, primaryKey);
            return (T) o;
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    @SuppressWarnings("unchecked")
    public List listAll() {
        try {
            final Session s = getSession(false);
            final Criteria c = s.createCriteria(objectClass);
            addOrderToCriteria(c);
            return c.list();
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

     @SuppressWarnings("unchecked")
    public List findByExample(final T example) {
        try {
            final Session s = getSession(false);
            final Criteria c = s.createCriteria(objectClass);
            c.add(Example.create(example).enableLike(MatchMode.ANYWHERE).ignoreCase().setPropertySelector(this));
            addOrderToCriteria(c);
            addPropertiedToCriteria(c, example);
            return c.list();
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    protected void addPropertiedToCriteria(final Criteria c, final T example) {
    }

    @SuppressWarnings("unchecked")
    public List findByExample(final T example, final int first, final int max) {
        try {
            final Session s = getSession(false);
            final Criteria c = s.createCriteria(objectClass);
            c.add(Example.create(example).enableLike(MatchMode.ANYWHERE).ignoreCase().setPropertySelector(this));
            addPropertiedToCriteria(c, example);
            addOrderToCriteria(c);
            if (first != 0) {
                c.setFirstResult(first);
            }
            if (max != 0) {
                c.setMaxResults(max);
            }
            return c.list();
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    @SuppressWarnings("unchecked")
    public List listAll(final int first, final int max) {
        try {
            final Session s = getSession(false);
            final Criteria c = s.createCriteria(objectClass);
            addOrderToCriteria(c);
            if (first != 0) {
                c.setFirstResult(first);
            }
            if (max != 0) {
                c.setMaxResults(max);
            }
            return c.list();
        } catch (final HibernateException ex) {
            TOBaseHibernateDao.logger.error(ex);
            throw convertHibernateAccessException(ex);
        }
    }

    protected void addOrderToCriteria(Criteria c) {
    }

    public boolean include(Object propertyValue, String propertyName, Type type) {
        if((propertyValue!=null) && (propertyValue instanceof String)){
            return !"".equals(((String)propertyValue).trim());
        }
        return propertyValue!=null;
    }
}

onde o método addOrderToCriteria, permite que subclasses deste DAO ordenem as consultas …
o método addPropertiedToCriteria permite que subclasses adicionem propriedades não incluidas pelo hibernate nas consultas …
e o método include combinado com o setPropertySelector da classe Example é uma melhoria adicionada a pouco tempo, que faz o mesmo que o addPropertiedToCriteria, mas de forma automática, ou seja, inclui as propriedades PK e FK também na QBE …

Bom, depois disto tudo, só falta criar o DAO para alguma entidade persistida pelo Hibernate, como por exemplo uma classe Curriculo …

Criamos a interface do nosso DAO:

package br.com.techoffice.site.dao;

import br.com.techoffice.site.data.Curriculo;

public interface CurriculoDao extends TOBaseDao{
}

e logo depois a implementação deste DAO:

package br.com.techoffice.site.dao.impl;

import net.java.dev.springannotation.annotation.Bean;
import br.com.techoffice.site.dao.CurriculoDao;
import br.com.techoffice.site.data.Curriculo;

@Bean(name="curriculoDao")
public class CurriculoDaoImpl extends TOBaseHibernateDao implements CurriculoDao {
	private static final long serialVersionUID = 1L;

	public CurriculoDaoImpl() {
        super(Curriculo.class);
    }
}

acho que era isto, o que acharam deste DAO genérico?
pela minha experiência, ele resolve de maneira estupidamente fácil em torno de 60% dos meus problemas de persistencia, nos outros 40% ai é necessário criar algum outro metodo de pesquisa especializado para cada situação …

mas acho que é esta a ideia das coisas genéricas, facilitar a maior parte do trabalho e permitir que a menor parte seja feita com um pouquinho de trabalho extra 😀 o que vocês acham?

Fonte: Blog do Urubatan

Advertisements

About Gustavo Amaro

+ Formado em Tecnologia e Análise de Sistemas + MBA em Desenvolvimento de Aplicações JAVA – SOA

Posted on 21 de Fevereiro de 2013, in Hibernate, Java, Persistência and tagged , , , , , , , , , , , . Bookmark the permalink. 2 comentários.

  1. Como que fica a ligação com o objeto com o managebean

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s

%d bloggers like this: