Olá, pessoal já li várias discussões sobre Repository X Dao aqui no GUJ, mas ainda assim algumas dúvidas persistem. Atualmente
trabalho com uma arquitetura definida assim:
Uma interface Dao
package br.com.oticaweb.persistence.dao;
public interface Dao<T> {
public void save(T t);
public void save_or_update(T t);
public void update(T t);
public void delete(T t);
public T get(Serializable id);
public T load(Serializable id);
public List<T> findAll();
public List<T> findAllByExample(T object);
public List<T> findAllByExample(T object, String orderBy);
public List<T> findAllByExampleWithPagination(T object,int min, int max);
public T findByExample(T object);
A implementação com Hibernate
class HibernateDao<T> implements Dao<T> {
protected Session session;
protected Class<T> persistenceClass;
public HibernateDao(Session session, Class<T> persistenceClass) {
super();
this.session = session;
this.persistenceClass = persistenceClass;
}
public void save(T t) {
session.save(t);
}
public void save_or_update(T t) {
session.saveOrUpdate(t);
}
public void delete(T t) {
session.delete(t);
}
public void update(T t) {
session.update(t);
}
@SuppressWarnings("unchecked")
public T get(Serializable id) {
return (T) session.get(persistenceClass, id);
}
@SuppressWarnings("unchecked")
public T load(Serializable id) {
return (T) session.load(persistenceClass, id);
}
@SuppressWarnings("unchecked")
public List<T> findAll() {
Criteria c = session.createCriteria(persistenceClass);
return c.list();
}
protected Integer countByCriterion(Criterion criterion) {
Criteria c = session.createCriteria(persistenceClass);
c.add(criterion);
c.setProjection(Projections.rowCount());
return (Integer) c.uniqueResult();
}
@SuppressWarnings("unchecked")
public List<T> findAllByExample(T object) {
Example example = Example.create(object).ignoreCase().enableLike(
MatchMode.ANYWHERE);
Criteria c = session.createCriteria(persistenceClass);
c.add(example);
return c.list();
}
@SuppressWarnings("unchecked")
public List<T> findAllByExample(T object, String orderBy) {
Example example = Example.create(object)
.ignoreCase()
.enableLike(MatchMode.ANYWHERE);
Criteria c = session.createCriteria(persistenceClass);
c.add(example);
c.addOrder(Order.asc(orderBy));
return c.list();
}
@SuppressWarnings("unchecked")
public List<T> findAllByExampleWithPagination(T object, int min, int max) {
Integer count = 0;
Example example = Example.create(object)
.ignoreCase()
.enableLike(MatchMode.ANYWHERE);
Criteria c = session.createCriteria(persistenceClass);
c.add(example);
count = countByCriterion(example);
if (count < max)
max = count;
if (min >= 0)
c.setFirstResult(min);
if (max >= 0)
c.setMaxResults(max);
return c.list();
}
@SuppressWarnings("unchecked")
public T findByExample(T object) {
Example example = Example.create(object)
.ignoreCase();
Criteria c = session.createCriteria(persistenceClass);
c.add(example);
return (T) c.uniqueResult();
}
}
Ai quando quero algum metodo novo crio uma interface tipo:
public interface FuncionarioDao extends Dao<Funcionario> {
public List<Funcionario> findAllByNameAndId(String name, Serializable id, int min,int max)throws NoResultException;
}
E implemento com um FuncionarioDaoImpl assim:
FuncionarioDaoImpl extends HibernateDao<Funcionario> implements FuncionarioDao{
@SuppressWarnings("unchecked")
public List<Funcionario> findAllByName(String name, int min, int max) throws NoResultException {
Integer count = 0;
Criteria c=session.createCriteria(Funcionario.class);
Conjunction conjunction=Restrictions.conjunction().add(Restrictions.eq("id", "id")).add(Restrictions.ilike("nome", name,MatchMode.ANYWHERE));
c.add(conjunction);
count = countByCriterion(conjunction);
if (count < max)
max = count;
if (min >= 0)
c.setFirstResult(min);
if (max >= 0)
c.setMaxResults(max);
return c.list();
}
Ai disponibilizo uma Factory para criação dos Daos onde injeto a Session assim:
public class DaoFactory {
private final Session session;
public DaoFactory() {
session=HibernateUtil.currentSession();
}
public FuncionarioDao getFuncionarioDao(){
return new FuncionarioDaoImpl(session,Funcionario.class);
}
public FilialDao getFilialDao() {
return new FilialDaoImpl(session,Filial.class);
}
public Dao<Secao> getSecaoDao(){
return new HibernateDao<Secao>(session,Secao.class);
}
}
Agora minhas dúvidas :
Acabando achando desnecessário interface Dao, pois se por exemplo se amanha quiser mudar a camada de Persistencia para JPa por exemplo, ficaria dificl implentar metodos como findByExample,por isso acho minha interface acoplada demais ao Hibernate.
Então qual seria a desvantagem de não ter interfaces trabalhando direto com a implementação?
Outra dúvida, esse modelo acima, está mais para um Repository ou Dao, muito genta fala que o Repository e uma interface com Semântica melhor do que o Dao então neste caso poderia ter uma interface assim:
interface Repository<T>
public void add(T t);
public void remove(T t);
O problema aqui é, onde entraria os metodos findAllByExample, no Repository ou nos Dao’s?
Como podem ver estou um pouco confuso com estes dos Patterns.
Se alguem puder esclarecer agradeço.