![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 2 Pomógł: 0 Dołączył: 18.02.2011 Ostrzeżenie: (0%) ![]() ![]() |
Witam,
większość z was na pewno zna poradnik Quickstart w dokumentacji ZendFrameworka. Jest tam przykład budowy prostej książki gości. I teraz chciałem zrobić katalog książek w ZF. Mam w bazie tabelki: Book, Author, Book_Author, Book_Genre, itd. Bazując na przykładzie modelu z dokumentacji Quickstart mogę zrobić coś w tym stylu:
To jest w 90% kod z dokumentacji ZF. Ciekawe podejście, jedna klasa do obiektu książki ze zmiennymi takimi jak kolumny w bazie, druga klasa do operacji z bazą, której przesyłamy obiekt tej pierwszej klasy. To wszystko rozumiem i jest ok. Ale teraz dochodzę do tego, że chciałbym pobrać listę książek wraz z nazwiskami ich autorów, gatunkami do których są przypisane i wyświetlić taką listę np. 20 książek wraz z pełnymi informacjami o każdej. W tej chwili metoda FetchAll wyciąga mi wszystko z tabelki Book. Nie mam pojęcia w jaki sposób podejść do tego, żeby dołączyć do tego też dane z innych tabel. Tabela Author_Book jest do relacji między książkami i autorami. (czyli książka ma kilku autorów). Nie wiem jak to ładnie zrobić żeby było zgodne z MVC itd. Czy porzucić całkowicie tej sposób z dwoma klasami czy nie, po prostu proszę o wskazówki w jaki sposób się takie coś robi. pozdrawiam! |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 172 Pomógł: 9 Dołączył: 13.02.2006 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 2 Pomógł: 0 Dołączył: 18.02.2011 Ostrzeżenie: (0%) ![]() ![]() |
chodziło mi bardziej o to, czy pobierać z bazy dane o autorach powinienem w metodzie FetchAll klasy Application_Model_BookMapper i czy nazwiska autorów mają trafić do obiektu klasy Application_Model_Book. Czy może metoda FetchAll klasy Application_Model_BookMapper powinna poprosić metodę klasy Application_Model_AuthorMapper o autorów. Czy może powinienem pobrać same dane z tabelki Book i kontroler powinien na ich podstawie poprosić o autorów klasę modelu związanego z tabelką Autorów.
Jeśli zrobię wszystko w metodzie FetchAll klasy Application_Model_BookMapper to jakoś tak??:
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 172 Pomógł: 9 Dołączył: 13.02.2006 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Metoda fetchAll() - to jest standardowa metoda Zend_Db_Abstract - pobiera ona wszystkie rekorny z konkretnej tabeli.
Nadpisywanie jej nie sadze ze jest dobrym pomyslem. Raczej proponuje ci stworzyc nowa metode publiczna fetchAllBook() i w niej napisac sobie zapytanie na podstawie Zend_Db_Select i tak pobrac dane. I mowie poczytaj o Zend_Db_Select - bo tak Ci nie wyjdzie za bardzo laczenie tabel Przyklad :
Pozdrawiam Ten post edytował quality 18.02.2011, 15:32:57 |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 66 Pomógł: 11 Dołączył: 25.07.2012 Ostrzeżenie: (0%) ![]() ![]() |
Witam, chciałbym odświerzyć nieco temat, ponieważ męczy mnie to samo zagadnienie co @markus12. Chodzi mi dokładnie jak najlepiej rozwiązać problem, gdy potrzebujemy pobrać "przysłowiową" książkę, oraz jej autorów, gatunek, etc. Oczywiście możemy zrobić funckję fetchAllBook(), ale zastanawia mnie jej zawrtość.
Użytkownik @quality, podał rozwiązanie bazujące na Zend_Db_Select wszsytko jest okej, ale wynik zwracany jest w postaci tablicy, kórej część pól nie ma odwzorowania w modelu Book. Zakładając, że przyjmujemy, iż mapper zwraca nam obiekt, to jakie atrybuty powinna posiadać klasa Book?
Męczy mnie to zagadnienie, i nie bardzo mogę znaleźć rozwiązanie które by mnie satysfakcjonowało. Bo teraz szybko się okaże, że trzeba będzie wyświetlić obok listy książki i autorów, np.: gatunek, dział w którym się znajduje oraz np.: budynek. Model będzie się rozrastał i rozrastał. Rozbudujemy obiekt wg. sposobu opisanego wyżej. Idąc dalej krokiem, będzie potrzeba w którymś miejscu wyświetlić jescze adres budynku w którym ta książka się znajduje, i mamy (np.: w widoku):
W takiej sytuacji robi się pewne misz-masz, bo na jednej liście (widoku) będziemy potrzebować wszystkich danych (łącznie z działem i budynkiem), a w innym widoku (bez tych dodatkowych danych). Wywołując fetchAllBook (w maperze) pakujemy obiekt złożony mimo, że nie zawsze jest on potrzebny. Można zrobić tak, że w modelu Book, zrobić tak, że:
Jednakże w takiej sytuacji przy foreachowaniu $oBook będziemy za każdym razem wysyłali dodatkowe sqlki. Jak rozwiązujecie takie sytuacje?? Ten post edytował Lysiur 14.12.2012, 10:54:40 |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 279 Pomógł: 60 Dołączył: 25.02.2012 Ostrzeżenie: (0%) ![]() ![]() |
Ja robię różnie w zależności od potrzeb. Chodzi głównie o wydajność pobierania danych z bazy. Im więcej zapytań, tym gorzej, więc lepiej robić jedno zapytanie pobierające dane do tabeli głównej z 3 joinami, niż 4 oddzielne zapytania. Ale... różnie to bywa, bo po pierwsze, zależy ile jest na raz wierszy pobieranych, ile joinowanych tabel i ile kolumn mają te tabele, bo budowanie i wypełnianie tych wszystkich obiektów-modeli zabiera czas i zużywa pamięć, i może to być naprawdę duży problem. Dlatego trzeba to wyważyć. Można też pisać sobie specjalne metody do pobierania różnych zestawów danych w zależności od zapotrzebowania - np. na jednym widoku potrzebujesz wyświetlić tylko 2 kolumny z tabeli A, a na innym 3 kolumny z tabeli A i jeszcze 8 kolumn z joinowanych tabel B, C i D - więc dwie różne metody będą w sam raz.
Poza tym, do pobierania danych tylko-do-odczytu (tylko do prezentacji) nie trzeba ich pobierać jako obiektów ORM, a wystarczą przecież proste zapytania SQL i wyniki tablicowe - potrafi to być znacznie wydajniejsze, niż pobranie tych samych danych za pomocą modeli. Modele są dobre głównie do logiki biznesowej i zapisu danych - bardzo wygodne, w zasadzie trudno je przecenić. Ale wyświetlanie (zwykle jest o kilka rzędów wielkości więcej operacji odczytu, niż zapisu) nie potrzebuje modeli - dedykowane, zoptymalizowane zapytania SQLowe o konkretne dane, zwracane jako tablice, potrafią być zdecydowanie wydajniejsze (wszystko zależy od obciążenia strony i ilości pobieranych danych oraz skomplikowania zapytań). |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 66 Pomógł: 11 Dołączył: 25.07.2012 Ostrzeżenie: (0%) ![]() ![]() |
Dziękuje @irmidjusz za odpowiedź, myślałem ostatnio nad tym co napisałeś, a przede wszystkim jak najoptymalnie zwracać wyniki (np.: złączonych kilku tabel) z Mappera. Domyślnie mapper powinien zwracać nam obiekt, ponieważ faktycznie często będzie tak, że zawartość złączonych tabelach będzie miała w jednym widoku 3 kolumny A, 2 B lub w innej konfiguracji. Niestety często jest tak, że w takich sytuacjach przydało by mi się na wejściu dostać obiekt, który byłby w stanie z wybranych atrybutów danego obiektu, np.: person zwrócić tablicę zawierającą id,firstName,surname, gdyż np.: z takiej tablicy poprzez helpera tworzę link do profilu czy ajaxowe okienko. Dlatego wygoniej będzie i jendolicie będzie wywołać w widoku
Pomyślałem, że zrobię clasę, np.: PersonList, który miałby wszystkie wymagane pola (zwracane, przez którekolwiek zapytanie łączące tabele). Zwracany wynik przez fetchAll() - czyli tablica, mapper wstawiałby mi to w klasę typu (kolekcji) PersonsCollection (implementująca Iterator,Countable), i przypadku chęci pobrania danego wiersza (złączonego z kilku tabel), zwracałby właśnie new PersonList(); Aczkoliwek, to narazie koncepcja, wyjdzie w praniu czy takie rozwiązanie ma sens, i czy nie jest zbyt zasoborzerne. Napewno będzie "cięższe" niż przekazanie samej tablicy zwracane przez mapper'a, ale rozwiązanie może ujednolicić kod. |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 2 958 Pomógł: 574 Dołączył: 23.09.2008 Skąd: wiesz, że tu jestem? Ostrzeżenie: (0%) ![]() ![]() |
Weź pod uwagę fakt, że zapytanie, które łączy kilka tabel, może zwrócić coś takiego:
a co gorsza to samo zapytanie, może zwrócić
lub
edit: do dzisiaj nie znalazłem odpowiedniej metody przekształcania tego typu danych w obiekt bez użycia:
(IMG:style_emoticons/default/wink.gif) Ten post edytował CuteOne 20.12.2012, 12:39:37 |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 54 Pomógł: 1 Dołączył: 29.03.2007 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Spotkałem się kiedyś z modelami pomocniczymi agregującymi inne modele dziedziczące bo Zend_Db_Table. Zrobione to było na zasadzie Dependency Injection. Modele pomocnicze nie miały swoich tabel w bazie, a jedynie obsługiwały i łączyły standardowe modele.
|
|
|
![]() ![]() |
![]() |
Aktualny czas: 22.08.2025 - 23:50 |