wzorzec DAO - czy pisać osobne DAO dla każdego entity?

0

siemacie
Mam w projecie 3 Entity. Chce je zapisywac w bazie danych za pomocą Hibernate. I tak: jeśli chodzi o operacje na bazie danych rozumiem, że powinienem zrobić implementacje klasy DAO (chociaż słyszałem, że przy większych projektach się ich pozbywa - ze wzgledu na to że narzucają większą liczbe kodu do wykonania co opóźnia, ale to tylko taka anegdota). I dzieki tej klasie jakiekolwiek operacje na bazie opakowywać właśnie w metody klasy DAO?

Stąd wnioskuje, że każde entity będzie miało swoja osobną klase DAO, tak? Bo jesli np mam podstawowe 5 metod(CRUD + wyciaganie całej tabeli): tworzenie(C), czytaj po id(R), czytaj wszystkich, edytuj(U), usun(D) - i np stwierdze że jeszcze według czegos-tam chce wyciagac z tabeli, to mam w interfejsie stworzyc kolejna metode i zaimplementowac ją w klasie DAO?

Dąże do tego, czy liczba metod klasy DAO jest jakoś ograniczona? może jest jakiś wzorzec/podejście, żeby nie powtarzac metod np. wyciaganie po: ID, imieniu, nazwisku itd.

Jeśli chodzi o osobne DAO dla każdego entity - domyślam się, że mozna napisać interfejs, zaimplementowac go w generycznym DAO i po prostu miec jedno DAO na każde entity. Jednak - nie na każdym obiekcie wykonam te same zapytania do bazy, stąd dla np 10 Entity to generyczne DAO sie rozrośnie do ogromnej liczby linijek.

Mam wrażenie, że troche cięzko mi wyszedł przekaz w tym poście :D przepraszam z góry, ale jakoś mało twórczy dziś jestem :)

licze na wyrozumiałość pozdrawiam

0

Z projektów wszelakich jakie robiłem.

  1. Operacje CRUD + wyciąganie wszystkiego umieszczamy w klasie abstrakcyjnej po której dziedziczą konkretne klasy dla encji.
  2. Zazwyczaj wystarczy implementacja metody w rodzaju enitityClass by podać do EntityManagera klasę po której wyszukujemy.
  3. Można dopisać metodę searchByFilter, która przyjmie sobie jako parametr listę warunków napisanych w ramach Criteria API, albo "ręcznie" łączących pola i wartości po to by przetworzyć ten parametr do właściwego zapytania.
  4. Przydaje się też metoda do wołania NamedQuery i NativeQuery.

Specyficzne wyszukiwania przerzucasz do pod klas. Tu można zastosować pewną sztuczkę polegającą na tym, że w podklasie wywolanie np. findByNazwa konfiguruje filtr i woła searchByFilter.

0

Ad.1 i 2: zakladam ze uzywa sie generykow, czyli hierarchia wyglada np. tak:

AbstractDao<T>

CustomerDao extends AbstractDao<Customer>
EmployeeDao extends AbstractDao<Employee>

to widac, ze pewne informacje sie powtarzaja - mianiowicie, w extends widac jakies klasy Dao produkujemy, wiec po co jeszcze raz podawac to samo? Mozna sobie metode entityClass czy np. parametr do konstruktora darowac. Wystarczy w konstruktorze AbstractDao taka magiczna linijka:

this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

Dziala to tak, ze ten kod jest wywolywany gdy this jest instancja podklasy (np. CustomerDao), zatem getGenericSuperclass() zwroci AbstractDao<Customer>, i getActualTypeArguments()[0] zwroci Type Customer; jako ze wiemy ze to jest klasa, rzutujemy to na Class<T> (ktore jest Class<Customer> w tym wypadku) i przypisujemy do pola.

Ten kod ma swoje wady (magia! nie wszyscy lubia) i zalety (pisany tylko raz w klasie bazowej, zero powtarzania sie), kazdy musi zdecydowac sam. Ja najczesciej jak mam takie cos pisac to wlasnie tak robie.

0

A ja od siebie dorzucę coś innego, tak żeby każdy mogł się sam dla siebie zastanowić czy w ogóle potrzebuje DAO, czy może EntityManager już ma to wszystko i nie potrzebuje dodatkowej warstwy http://www.adam-bien.com/roller/abien/entry/how_to_treat_the_jpa

1

Jak dla mnie to EM jest zbyt niskopoziomowy. Wolalbym miec metody ktore brzmia EmployeeDao.findByName(String name) niz za kazdym razem gdy potrzebuje liste na podstawie imion tworzyc zapytania w kodzie. Nie wspominajac o bardziej wymagajacych queriesach.

1 użytkowników online, w tym zalogowanych: 0, gości: 1