Friday, December 19, 2014

DAO layer



In MVC (Model-View-Controller) pattern very often is using DAO (Data Acces Object) component, I may say that is a widely accepted mechanism to abstract away the details of persistence in an application. Data Acces Object supplies uniform interface to comunicate beteween application and data source (i.e. database or file). Owing to DAO layer, application can made some specific operation, typically for acces to data.

Here is how it looks:

Mostly are using CRUD (create-read-update-delete) operation. Thanks to those operation we don't need create and implement many classes and SQL query to manage connection between application and database and input data to them.

In my project DAO layer was divide for two pats:
1. DAO files with AbstractDAO files, which are interfaces;
2. DAO Implement files , hose are classes which imlements above interfaces.

Project tree looks:


In AbstractDAO files defined method, which next are overriding and implements in other DAO files.
AbstractDAO are below:
 package com.pizza.delivery.services;  
 import java.io.Serializable;  
 import java.util.List;  
 public interface AbstractDAO <E, K extends Serializable>{       
      E create(E entity);  
      E update(E entity);  
      void delete(K key);  
      E findById(K key);  
      List<E> listAll();  
 }  
Implemented those operation was in AbstractDAOImpl file which looks:

 package com.pizza.delivery.services.impl;  
 import java.io.Serializable;  
 import java.lang.reflect.ParameterizedType;  
 import java.util.List;  
 import javax.persistence.EntityManager;  
 import javax.persistence.PersistenceContext;  
 import org.hibernate.Criteria;  
 import org.hibernate.Session;  
 import org.springframework.transaction.annotation.Propagation;  
 import org.springframework.transaction.annotation.Transactional;  
 import com.pizza.delivery.services.AbstractDAO;  
 /**  
  * Basic DAO operations dependent with Hibernate's specific classes  
  *   
  * @see EntityManager  
  */  
 @Transactional(propagation = Propagation.REQUIRED, readOnly = false)  
 public abstract class AbstractDAOImpl<E, K extends Serializable> implements  
           AbstractDAO<E, K> {  
      @PersistenceContext  
      protected EntityManager entityManager;  
      protected Class<E> entityClazz;  
      @SuppressWarnings("unchecked")  
      public AbstractDAOImpl() {  
           entityClazz = (Class<E>) ((ParameterizedType) (getClass().getGenericSuperclass()))  
                     .getActualTypeArguments()[0];  
      }  
      public EntityManager getEntityManager() {  
           return entityManager;  
      }  
      public void setEntityManager(EntityManager entity) {  
           this.entityManager = entity;  
      }  
      // /////////////////////////////Create///////////////////////////////////////  
      @Override  
      public E create(E entity) {  
           this.entityManager.persist(entity);  
           this.entityManager.flush();  
           //this.entityManager.merge(entity);  
           return entity;  
      }  
      // /////////////////////////////Update/////////////////////////////////////  
      @Override  
      @Transactional(propagation = Propagation.REQUIRES_NEW)  
      public E update(E entity) {  
           E result = this.entityManager.merge(entity);  
           entityManager.flush();  
           return result;  
      }  
      // ////////////////////////Delete//////////////////////////////////////////  
      @Override  
      @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = IllegalArgumentException.class ,noRollbackFor = IllegalArgumentException.class)  
      public void delete(K key) {  
           E entity = entityManager.find(entityClazz,key);            
                this.entityManager.remove(entity);  
      }  
      // /////////////////////////////FindById///////////////////////////////////  
      @Override  
      public E findById(K key) {  
           return entityManager.find(entityClazz, key);  
      }  
      @SuppressWarnings("unchecked")  
      public List<E> listAll() {  
           final Session session = (Session) entityManager.getDelegate();  
           final Criteria crit = session.createCriteria(entityClazz);  
           return crit.list();  
      }  
 }  

Those method supports most operations to add, update, delate and searching in database. O the project tree except AbstractDAO files there are file which represent all of the domain files, there are entity represent table from database. If we want implements some specific operation typical for one entity we may implement in typical class for the table. For example, in IngredientDAO file defined method:

 package com.pizza.delivery.services;  
 import java.util.List;  
 import com.pizza.delivery.domain.Ingredient;  
 public interface IngredientDAO<Igredient> extends AbstractDAO<Igredient, Long>{  
      List<Ingredient> findByName(String name);  
 }  


Those method will be useful for create new pizza, adding special ingredients in ordering or create my own pizza. Implemented is in in IngredientDAOImpl and looks like below:

package com.pizza.delivery.services.impl;  
 import java.util.List;  
 import javax.persistence.TypedQuery;  
 import javax.persistence.criteria.CriteriaBuilder;  
 import javax.persistence.criteria.CriteriaQuery;  
 import javax.persistence.criteria.ParameterExpression;  
 import javax.persistence.criteria.Root;  
 import org.springframework.stereotype.Repository;  
 import com.pizza.delivery.domain.Ingredient;  
 import com.pizza.delivery.services.IngredientDAO;  
 @Repository  
 public class IngredientDAOImpl extends AbstractDAOImpl<Ingredient, Long>  
           implements IngredientDAO<Ingredient> {  
      @Override  
      public List<Ingredient> findByName(String name) {  
           // TODO Auto-generated method stub  
           CriteriaBuilder cb = entityManager.getCriteriaBuilder();  
           CriteriaQuery<Ingredient> query = cb.createQuery(Ingredient.class);  
           Root<Ingredient> c = query.from(Ingredient.class);  
           ParameterExpression<String> nameParam = cb.parameter(String.class,  
                     "name");  
           query.select(c).where(cb.equal(c.get("name"), nameParam));  
           TypedQuery<Ingredient> typedQuery = entityManager.createQuery(query);  
           typedQuery.setParameter("name", name);  
           return typedQuery.getResultList();  
      }  
 }  


In this class we can see that entityManager using JPA contener getting object from database, I'm using SQL query inject in JPA.










aaaaa

No comments:

Post a Comment