2010-10-08 17 views
43

Po poprzednim pytaniu, DAO and Service layers (JPA/Hibernate + Spring), postanowiłem użyć tylko jednego DAO dla mojej warstwy danych (przynajmniej na początku) w aplikacji używającej JPA/Hibernate, Wiosna i furtka. Zaproponowano użycie ogólnych metod CRUD, ale nie jestem pewien, jak to zaimplementować za pomocą JPA. Czy mógłbyś podać mi przykład lub podzielić się linkiem dotyczącym tego?Pojedyncze DAO i ogólne metody CRUD (JPA/Hibernate + Spring)

Odpowiedz

84

Oto przykład interfejs:

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

i realizacja:

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

Jak by to dopasować się obiekty slsb i pojo (reprezentujące tabele db)? – NimChimpsky

+3

Świetna odpowiedź. Kilka uwag: raczej przekazuję klasę jako parametr w metodzie konstruktora (zamiast odznaczonego rzutowania); parametr t w metodzie delete nie powinien być ponownie przypisywany, a klasa powinna być abstrakcyjna. – megathor

+0

Dzięki !!!!!!!! DUŻO! – verystrongjoe

5

Szukałem tego samego. Znalazłem coś, co wydaje się dokładnie takie - projekt JPA dostarczony przez SpringSource. Jest to port kodu od Hades i został już (na początku 2011 r.) Połknięty przez wiosnę i lepiej zintegrowany. Pozwala na użycie pojedynczego dao (SimpleJpaRepository) ze statycznym tworzeniem lub rozszerzeniem podstawowej klasy JpaRepository w celu utworzenia dowolnego obiektu dao z gotowymi metodami CRUD +. Pozwala również na granie typu zapytania, używając nazw paramu jako nazwy metody - w interfejsie (nie wymaga implementacji!), Tj. findByLastname(String lastName); Wygląda bardzo obiecująco - bycie częścią projektów wiosennych z pewnością zapewni jej również pewną przyszłość. Zacząłem wdrażać to w moim nadchodzącym projekcie.

14

Na podstawie artykułu Don't repeat the DAO używaliśmy tego rodzaju techniki przez wiele lat. Zawsze zmagaliśmy się z problemami z naszymi wzorami, gdy zdaliśmy sobie sprawę, że popełniliśmy wielki błąd.

Korzystając z narzędzia ORM, takiego jak Hibernate lub JPA, nie musisz osobno myśleć o kategoriach DAO i Service. Możesz użyć EntityManager ze swoich klas usług, ponieważ znasz cykl życia transakcji i logikę tam swoich klas jednostek.

Czy zapisujesz w dowolnej chwili, dzwoniąc pod numer myDao.saveEntity zamiast po prostu entityManager.saveEntity? Nie. Będziesz mieć niepotrzebną klasę dao, która nie zrobi nic innego, ale będzie opakowaniem wokół EntityManager. Nie bój się pisać wyborów w swoich klasach usług przy pomocy EntityManager (lub sesji w hibernacji).

Jeszcze jedna uwaga: Należy zdefiniować granice warstwy usługi i nie pozwolić programistom na zwrócenie lub oczekiwanie na klasy jednostek. Programowanie warstwy UI lub WS nie powinno w ogóle wiedzieć o klasach jednostek tylko o DTO-s. Obiekty obiektów mają cykle życia, o których większość programistów nie wie. Będziesz miał naprawdę poważne problemy, jeśli przechowujesz obiekt obiektu w danych sesji i spróbuj zaktualizować go z powrotem do bazy danych sekund lub godzin później. Cóż, nie zrobiłbyś tego, ale programista interfejsu użytkownika, który zna typy parametrów i typy zwracanych warstw serwisowych, zrobiłby tylko kilka linii kodu.

+0

Zarządzanie transakcjami z adnotacjami w EJB ?! Chociaż prawdopodobnie potrzebujesz znacznie bardziej wyrafinowanego DAO, który nie będzie już generyczny, ale tak czy inaczej. Wciąż uważam, że ta metoda może być przydatna w konkretnych przypadkach. –