2015-03-13 24 views
1

我需要在這裏絞盡腦汁! :PCDI GenericDAO和自定義實現

我有一個接口IDAO < T,K>,T是實體類和K的主鍵類。

我開發了一個具體的類GenericDAO < T,K>,它提供了CRUD操作和Criteria查詢自動提取(我創建了一個用於實體關係的@Joinfetch)。我可以顯示代碼,如果你想,但它不是主題:)。

這裏產生GenericDAOs工廠:

public class GenericDAOProducer { 

@PersistenceContext 
EntityManager em; 

@Produces 
@Default 
public <T, K> IDAO<T, K> producesGenericDAO(
     final InjectionPoint injectionPoint) { 
    final ParameterizedType type = (ParameterizedType) injectionPoint 
      .getType(); 
    // Because of the new, i got to inject the class and the entity manager 
    // manualy 
    final IDAO<T,K> dao = new GenericDAO<T, K>(this.em, 
      (Class) type.getActualTypeArguments()[0]); 
    dao.init(); //cool stuff here to prepare some criteria queries 
    return dao; 
} 
} 

有時候,我需要的DAO另一個實現(複雜取的爲例)。這些實現也通過IDAO外觀展示了他們的方法。我希望這些DAO以與GenericDAO相同的方式注入。

這裏是我想在個例的特徵:

我需要IDAO <的人,龍>某處的一個實施注射。 如果存在類實現IDAO < Person,那麼Long>然後我要CDI選擇這個實現。 否則,如果爲IDAO <人沒有實現存在,龍>我想CDI選擇GenericDAO <人,龍>這個工廠生產的。

這是相當困難的,我解釋說,英文。我希望你能理解我的問題。

你有沒有做到這一點的最佳做法?

謝謝!

+0

我創造了一些非常酷做!我會很快分享:) – 2015-03-13 16:58:37

+0

您可能要基於CDI通用的DAO檢查出[DeltaSpike數據](http://deltaspike.apache.org/documentation/data.html)。 – 2015-03-14 17:01:53

+0

這是一個非常interresting API謝謝! 但我不認爲它創建沒有類的強類型DAO。 您需要按實體聲明至少一個@Repository。事情是我的應用程序庫存大量的數據,每個月我需要添加一個實體類與它的關係。然後我必須在每個級別編碼類。 使用我的模式,如果我想覆蓋或添加一些方法,我不需要編寫一個DAO代碼。 – 2015-03-16 10:00:04

回答

1

我需要兩個@Qualifier

@Qualifier 
@Retention(RUNTIME) 
@Target({ METHOD, FIELD, PARAMETER, TYPE }) 
public @interface Generic {} 


@Qualifier 
@Retention(RUNTIME) 
@Target({ METHOD, FIELD, PARAMETER, TYPE }) 
public @interface Specific { 
Class<?> classe(); 
} 

的IDAO接口

public interface IDAO<T, PK> extends Serializable { 

public abstract T create(T entity) throws DAOException; 

public abstract T edit(T entity) throws DAOException; 

public abstract void remove(T entity) throws DAOException; 

public abstract T find(PK id) throws DAOException; 

public abstract T findWithFetch(PK id) throws DAOException; 

public abstract List<T> findAll(); 

public abstract T getRef(PK id); 
} 

的IDefaultDAO

public interface IDefaultDAO<T, PK> extends IDAO<T, PK> { 
public void setEntityClass(final Class<T> entityClass); 
} 

抽象DAO

public abstract class AbstractDAO<T, PK> implements IDAO<T, PK> { 

@PersistenceContext 
protected EntityManager em; 

@Inject 
protected transient Logger logger; 

protected Class<T> entityClass; 

protected final Class<T> getEntityClass() { 
    if (this.entityClass == null) { 
     this.entityClass = ((Class) ((ParameterizedType) this.getClass() 
       .getGenericSuperclass()).getActualTypeArguments()[0]); 

    } 
    return this.entityClass; 
} 

//methods implementations 
} 

默認DAO

@Generic 
public class DefaultDAO<T, PK> extends AbstractDAO<T, PK> implements 
    IDefaultDAO<T, PK> { 

@Override 
public void setEntityClass(final Class<T> entityClass) { 
    this.entityClass = entityClass; 
} 
} 

一個具體的DAO

@Specific(classe=Delegation.class) 
public class DelegationDAO extends AbstractDAO<Delegation, Integer> 
implements IDAO<Delegation, Integer> { 
// do things differently 
} 

的DAO生產者

public class GenericDAOProducer { 

@Inject 
private transient Logger logger; 

@Produces 
public <T, PK> IDAO<T, PK> producesDAO(final InjectionPoint injectionPoint, 
     @Generic final IDefaultDAO<T, PK> genericDAO, 
     @Any Instance<IDAO<T, PK>> specDAOInstance) { 

    // JPA Class (T) 
    final ParameterizedType type = (ParameterizedType) injectionPoint 
      .getType(); 
    final Class<T> entityClass = (Class) type.getActualTypeArguments()[0]; 

    this.logger.info("Search DAO " + entityClass); 

    // Search specific DAO 

    specDAOInstance = specDAOInstance.select(new SpecificLiteral(
      entityClass)); 

    if ((specDAOInstance != null) && !specDAOInstance.isAmbiguous() 
      && !specDAOInstance.isUnsatisfied()) { 
     this.logger.info("Implementation found! "); 
     return specDAOInstance.get(); 
    } else { 

     this.logger 
       .info("Implementation not found! Return generic DAO." 
         + entityClass); 

     genericDAO.setEntityClass(entityClass); 
     return genericDAO; 
    } 
    } 
}