2010-10-08 36 views
43

Suite à ma question précédente, DAO and Service layers (JPA/Hibernate + Spring), j'ai décidé d'utiliser un seul DAO pour ma couche de données (au moins au début) dans une application utilisant JPA/Hibernate, Printemps et Wicket. L'utilisation de méthodes CRUD génériques a été proposée, mais je ne suis pas très sûr de savoir comment l'implémenter en utilisant JPA. Pourriez-vous s'il vous plaît me donner un exemple ou partager un lien à ce sujet?Méthodes DAO simples et CRUD génériques (JPA/Hibernate + Spring)

Répondre

84

Voici une interface exemple:

public interface GenericDao<T, PK extends Serializable> { 
    T create(T t); 
    T read(PK id); 
    T update(T t); 
    void delete(T t); 
} 

Et une mise en œuvre:

public class GenericDaoJpaImpl<T, PK extends Serializable> 
    implements GenericDao<T, PK> { 

    protected Class<T> entityClass; 

    @PersistenceContext 
    protected EntityManager entityManager; 

    public GenericDaoJpaImpl() { 
     ParameterizedType genericSuperclass = (ParameterizedType) getClass() 
      .getGenericSuperclass(); 
     this.entityClass = (Class<T>) genericSuperclass 
      .getActualTypeArguments()[0]; 
    } 

    @Override 
    public T create(T t) { 
     this.entityManager.persist(t); 
     return t; 
    } 

    @Override 
    public T read(PK id) { 
     return this.entityManager.find(entityClass, id); 
    } 

    @Override 
    public T update(T t) { 
     return this.entityManager.merge(t); 
    } 

    @Override 
    public void delete(T t) { 
     t = this.entityManager.merge(t); 
     this.entityManager.remove(t); 
    } 
} 
+2

Comment cela se inscrire dans Les entités slsb et pojo (représentant les tables db)? – NimChimpsky

+3

Bonne réponse. Juste quelques commentaires: je préfère passer la classe en tant que paramètre dans la méthode constructeur (au lieu d'une distribution non contrôlée); le paramètre t de la méthode delete ne doit pas être réaffecté et la classe sera de préférence abstraite. – megathor

+0

Merci !!!!!!!! BEAUCOUP! – verystrongjoe

5

Je cherchais la même chose. J'ai trouvé ce qui semble être exactement cela: le projet JPA Spring-Data fourni par SpringSource. Ceci est un port de code de Hades et a maintenant (début 2011) été avalé par le printemps et mieux intégré. Il vous permet d'utiliser un seul dao (SimpleJpaRepository) avec une création statique, ou d'étendre la classe JpaRepository de base pour créer un dao spécifique à un objet avec des méthodes CRUD + prêtes à l'emploi. Permet également des requêtes de type grails simplement en utilisant les noms de paramètres comme nom de la méthode dans l'interface (aucune implémentation nécessaire!) Par exemple findByLastname(String lastName); Cela semble très prometteur - faire partie des projets du printemps lui assurera assurément un certain avenir. J'ai commencé à implémenter ceci dans mon prochain projet maintenant.

14

Basé sur l'article Don't repeat the DAO nous avons utilisé ce genre de technique pendant de nombreuses années. Nous avons toujours eu des problèmes avec nos modèles après avoir réalisé que nous avions fait une grosse erreur. En utilisant un outil ORM tel que Hibernate ou JPA, vous n'aurez pas à penser aux couches DAO et Service séparément. Vous pouvez utiliser EntityManager à partir de vos classes de service lorsque vous connaissez le cycle de vie des transactions et la logique de vos classes d'entités. Enregistrez-vous une minute si vous appelez myDao.saveEntity au lieu de simplement entityManager.saveEntity? Non. Vous aurez une classe dao inutile qui ne fait rien d'autre mais qui sera un wrapper autour d'EntityManager. N'ayez pas peur d'écrire des sélections dans vos classes de service avec l'aide de EntityManager (ou session en hibernation). Une autre remarque: Vous devez définir les bordures de votre couche de service et ne pas laisser les programmeurs retourner ou attendre les classes Entity. Les programmeurs de couche UI ou WS ne devraient pas du tout connaître les classes d'entités à propos des DTO-s. Les objets d'entité ont des cycles de vie que la plupart des programmeurs ignorent. Vous aurez des problèmes vraiment sérieux si vous stockez un objet d'entité dans une donnée de session et essayez de le mettre à jour dans la base de données quelques secondes ou quelques heures plus tard. Eh bien, vous pourriez ne pas le faire, mais un programmeur de l'interface utilisateur qui connaît les types de paramètres et les types de retour de votre couche de service ne ferait que sauver quelques lignes de code.

+0

Gestion des transactions annotée dans EJB ?! Bien que vous ayez probablement besoin de DAO beaucoup plus sophistiqué, ce ne sera plus générique, mais de toute façon. Je trouve toujours que cette méthode peut être utile dans des cas spécifiques. –