- ObtenerId: Nos obtiene la entidad asociada a un id.
- Eliminar: Se encarga de eliminar la entidad que le pasamos.
- Actualizar: Se encarga de actualizar la entidad que le pasamos.
- Crear: Se encarga de crear un entidad.
- Obtener todos: Nos devuelve todos los registros del sistema.
El dao genérico, se compone de una interfaz y una clase que implementa las operaciones.
En el siguiente proyecto podéis encontrar https://github.com/blancoparis-tfc/SpringCrud
Interfaz
Lo primer que tenemos que hacer es definir las operaciones, en una interfaz, en la cual además de las operaciones, vamos a definir en la cabecera de la interfaz, dos tipos genéricos, que van a representar a la entidad con la que vamos a trabajar y el id de la entidad.Gracias a estos dos genéricos, es lo que va hacer la magia que nos va a permitir que estas operaciones valgan para cualquier de nuestras entidades del proyecto.
package org.dbp.core.dao; import java.io.Serializable; import java.util.List; public interface GenericDao{ public E obtenerId(ID id); public void eliminar(E entidad); public void crear(E entidad); public E actualizar(E entidad); public List obtenerTodos(); }
Clase
Ahora vamos a implementar las operaciones que hemos puesto en el interfaz, en la siguiente clase.package org.dbp.core.dao.impl; import java.io.Serializable; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; import org.dbp.core.dao.GenericDao; import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor=Exception.class) public class GenericDaoImplimplements GenericDao { @PersistenceContext private EntityManager em; private Class clazzE; public GenericDaoImpl(Class clazzE) { super(); this.clazzE = clazzE; } public E obtenerId(ID id){ return em.find(clazzE, id); } public void eliminar(E entidad){ em.remove(entidad); } public void crear(E entidad){ em.persist(entidad); } public E actualizar(E actualizar){ return em.merge(actualizar); } public List obtenerTodos(){ CriteriaBuilder cb=em.getCriteriaBuilder(); CriteriaQuery criteria=cb.createQuery(clazzE); Root from=criteria.from(clazzE); TypedQuery query=em.createQuery(criteria.select(from)); return query.getResultList(); } }
Ejemplo
Una vez definido el dao genérico, para ver todo su potencial es ver el uso y poder apreciar el ahorro de código por un lado, y por otro lado y mas importante que ahora estas operaciones las tenemos centralizadas y si el día de mañana queremos cambiarlas o añadir alguna a todas las entidades lo podemos hacer o cambiar la versión del ORM o lo que sea, nos facilitara la vida.package org.dbp.dao.impl; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.dbp.bom.Usuario; import org.dbp.core.dao.impl.GenericDaoImpl; import org.dbp.dao.UsuarioDao; import org.springframework.stereotype.Repository; @Repository public class UsuarioDaoImpl extends GenericDaoImplimplements UsuarioDao{ @PersistenceContext private EntityManager em; public UsuarioDaoImpl() { super(Usuario.class); } @Override public Usuario obtenerLogin(String login){ return em.createQuery("from Usuario u where u.login = :login",Usuario.class) .setParameter("login", login) .getSingleResult(); } }
Test
Para ver el funcionamiento he creado el siguiente test:package org.dbp.dao;
import static org.junit.Assert.*;
import java.util.List;
import org.dbp.bom.Usuario;
import org.dbp.core.config.TestConfiguracion;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@ContextConfiguration(classes = TestConfiguracion.class)
public class UsuarioDaoTest {
@Autowired private UsuarioDao usuarioDao;
@Test
public void testRecuperarTodos(){
List usuarios=usuarioDao.obtenerTodos();
assertEquals("Miramos el número de elementos",1,usuarios.size());
}
@Test
public void testObtenerPorId(){
Usuario usuario=usuarioDao.obtenerId(1L);
assertEquals("Validamos el ID:",new Long(1L),usuario.getId());
assertEquals("Validamos el loging","dblanco",usuario.getLogin());
}
@Test
public void testObtenerLogin(){
Usuario usuario=usuarioDao.obtenerLogin("dblanco");
assertEquals("Validamos el ID:",new Long(1L),usuario.getId());
assertEquals("Validamos el loging","dblanco",usuario.getLogin());
}
}