Si queremos evitar tener duplicado ese código y ahorrarnos la codificación de esas operaciones básicas podemos desarrollar un DAO genérico que nos sirva para todas las entidades persistentes de nuestra aplicación usando los generics del lenguaje Java. Las operaciones candidatas a incluir en este DAO son: búsqueda por id, persistencia de un objeto, borrado, actualización, búsqueda paginada de todos los objetos y número de entidades persistidas de un tipo.
El código que podemos usar puede ser el siguiente:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.tapestry.jpa.dao; | |
import java.util.List; | |
import org.apache.tapestry5.jpa.annotations.CommitAfter; | |
import es.com.blogspot.elblogdepicodev.tapestry.jpa.misc.Pagination; | |
public interface GenericDAO<T> { | |
T findById(Long id); | |
List<T> findAll(); | |
List<T> findAll(Pagination paginacion); | |
long countAll(); | |
@CommitAfter | |
void persist(T producto); | |
@CommitAfter | |
void remove(T producto); | |
@CommitAfter | |
void removeAll(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.tapestry.jpa.dao; | |
import java.util.List; | |
import javax.persistence.EntityManager; | |
import javax.persistence.Query; | |
import javax.persistence.criteria.CriteriaBuilder; | |
import javax.persistence.criteria.CriteriaQuery; | |
import javax.persistence.criteria.Root; | |
import es.com.blogspot.elblogdepicodev.tapestry.jpa.misc.Pagination; | |
public class GenericDAOImpl<T> implements GenericDAO<T> { | |
private Class<T> clazz; | |
private EntityManager entityManager; | |
public GenericDAOImpl(Class<T> clazz, EntityManager entityManager) { | |
this.clazz = clazz; | |
this.entityManager = entityManager; | |
} | |
@Override | |
public T findById(Long id) { | |
return entityManager.find(clazz, id); | |
} | |
@Override | |
public List<T> findAll() { | |
return findAll(null); | |
} | |
@Override | |
public List<T> findAll(Pagination paginacion) { | |
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); | |
CriteriaQuery<T> cq = cb.createQuery(clazz); | |
Root<T> root = cq.from(clazz); | |
cq.select(root); | |
if (paginacion != null) { | |
cq.orderBy(paginacion.getOrders(root, cb)); | |
} | |
Query q = entityManager.createQuery(cq); | |
if (paginacion != null) { | |
q.setFirstResult(paginacion.getStart()); | |
q.setMaxResults(paginacion.getEnd() - paginacion.getStart() + 1); | |
} | |
return q.getResultList(); | |
} | |
@Override | |
public long countAll() { | |
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); | |
CriteriaQuery<Long> cq = cb.createQuery(Long.class); | |
cq.select(cb.count(cq.from(clazz))); | |
return entityManager.createQuery(cq).getSingleResult().intValue(); | |
} | |
@Override | |
public void persist(T object) { | |
entityManager.persist(object); | |
} | |
@Override | |
public void remove(T object) { | |
entityManager.remove(object); | |
} | |
@Override | |
public void removeAll() { | |
String jpql = String.format("delete from %s", clazz.getName()); | |
Query query = entityManager.createQuery(jpql); | |
query.executeUpdate(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package es.com.blogspot.elblogdepicodev.tapestry.jpa.dao; | |
import javax.persistence.criteria.CriteriaBuilder; | |
import javax.persistence.criteria.CriteriaQuery; | |
import javax.persistence.criteria.Root; | |
public interface SimpleCriteriaBuilder<T> { | |
void build(CriteriaBuilder cb, CriteriaQuery<T> cq, Root<T> c); | |
} |
Código fuente completo del ejemplo
Persistencia con JPA y Apache Tapestry