Pessoal estou iniciando um projeto e gostaria de saber de vocês o que acham de alguns detalhes que estou implementando e o que preciso mudar também, criei um repositorio generico com a seguinte interface:
este repositório cobre bem os filtros do sistema e pode ser usado com o conceito de fluentInterfaces:
public interface Repositorio<ENTIDADE,REPOSITORIO> {
Integer contagem();
List<ENTIDADE> listagem();
List<ENTIDADE> listagem(int inicio,int numRegistros);
REPOSITORIO ordenadoPor(String campo,boolean descending);
REPOSITORIO igual(String campo,Object valor);
REPOSITORIO naFaixa(String campo,Object valorInicial,Object valorFinal);
REPOSITORIO contendo(String campo,String valor);
ENTIDADE resultadoUnico();
void salvar(ENTIDADE entidade);
void remover(ENTIDADE entidade);
}
um exemplo de utilização seria este:
repositorio.igual(“nome”,“carlos alberto”).ordenadoPor(“id”,true).listagem();
isto me retorna uma lista de todos com o nome carlos alberto ordenado por id:
segue a implementação da classe:
@SuppressWarnings("unchecked")
public class RepositorioImpl<ENTIDADE,REPOSITORIO> implements Repositorio<ENTIDADE,REPOSITORIO> {
protected Class<ENTIDADE> persistentClass;
public RepositorioImpl() {
Object entidade = this.getClass();
while(! (entidade instanceof ParameterizedTypeImpl)){
entidade = ((Class<ENTIDADE>) entidade).getGenericSuperclass();
}
this.persistentClass = (Class<ENTIDADE>) ((ParameterizedTypeImpl) entidade).getActualTypeArguments()[0];
}
@In
protected Session session;
@In
protected EntityManager em;
protected Criteria criteria = null;
public void setSession(Session session) {
this.session = session;
}
public void setEm(EntityManager em) {
this.em = em;
}
protected void initCriteria() {
if (criteria == null) {
criteria = session.createCriteria(persistentClass);
}
}
public Integer contagem() {
initCriteria();
criteria.setProjection(Projections.rowCount());
Integer result = (Integer) criteria.uniqueResult();
criteria = null;
return result;
}
public REPOSITORIO contendo(String campo, String valor) {
initCriteria();
criteria.add(Restrictions.ilike(campo, valor, MatchMode.ANYWHERE));
return (REPOSITORIO) this;
}
public REPOSITORIO igual(String campo, Object valor) {
initCriteria();
criteria.add(Restrictions.eq(campo, valor));
return (REPOSITORIO) this;
}
public ENTIDADE resultadoUnico() {
initCriteria();
ENTIDADE result = (ENTIDADE) criteria.uniqueResult();
criteria = null;
return result;
}
public List<ENTIDADE> listagem() {
initCriteria();
List<ENTIDADE> result = criteria.list();
criteria = null;
return result;
}
public List<ENTIDADE> listagem(int inicio, int numRegistros) {
initCriteria();
criteria.setFirstResult(inicio);
criteria.setMaxResults(numRegistros);
List<ENTIDADE> result = criteria.list();
criteria = null;
return result;
}
public REPOSITORIO naFaixa(String campo, Object valorInicial, Object valorFinal) {
initCriteria();
criteria.add(Restrictions.between(campo, valorInicial, valorFinal));
return (REPOSITORIO) this;
}
public REPOSITORIO ordenadoPor(String campo, boolean descending) {
initCriteria();
criteria.addOrder(descending ? Order.desc(campo) : Order.asc(campo));
return (REPOSITORIO) this;
}
public void remover(ENTIDADE entidade) {
ENTIDADE attachedEntity = em.merge(entidade);
em.remove(attachedEntity);
}
public void salvar(ENTIDADE entidade) {
Entidade entity = (Entidade) entidade;
if (entity.getId() != null)
em.merge(entity);
else
em.persist(entity);
}
}
agora para implementações uso o seguinte crio uma interface para o repositório que gostaria de criar e extendo a classe que implementa o repositorio, assim:
public interface RepositorioUsuario extends Repositorio<Usuario, RepositorioUsuario> {
}
public class DAOUsuario extends RepositorioImpl<Usuario, RepositorioUsuario> implements RepositorioUsuario {
}
caso tenha algum método especial de consulta que não é coberto pelo repositorio genérico, posso implementar no repositorio específico do sistema.
Esta é uma boa abordagem?