Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Templatowanie zapytań SQL w php
Forum PHP.pl > Forum > PHP
sniver
Zazwyczaj gdy spotykam kody różnego pokroju w PHP to czesto warstwa logiczna od wyglądu jest oddzielona.
Pal licho jeśli obsługa np. mysql'a jest w jakiś przystępny sposób zrobiona i do tego ktoś wykorzystał np. pdo i "przygotowywanie zapytań".

Ale często spotykam się też z kodami gdzie zapytanie jest przygotowywane strukturalnie i dość często przy nieco bardziej złożonych mam problemy z ich rozszyfrowaniem blinksmiley.gif

Powstaje więc pytanie czy: warto oddzielić tę warstwę (jeśli taka istnieje) bazy danych - czyli to gdzie te duperele są obsługiwane i wypisać zapytania tak by znajdowały się w oddzielnym pliku i stworzyć coś na wzór smarty?

Dla przykładu zapytanie
  1. SELECT
  2. `nazwa`,
  3. `opis`,
  4. `zdjecie`
  5. FROM
  6. `jakasTabela`
  7. {IF $id}
  8. WHERE
  9. `id` = {$id}
  10. {else}
  11. ORDER BY `id` DESC
  12. LIMIT 0, 30
  13. {/IF}


i np. taki kod w php który to przetworzy i wyciągnie zapytanie np. z xml:

  1.  
  2. $zapytanieOdczytaneZPlikuXML = ...;
  3.  
  4. $dbPattern = new ParserSQL;
  5. $dbPattern->assign('id', 123);
  6.  
  7. $dbPattern->parse( $zapytanieOdczytaneZPlikuXML );
  8.  
  9. // Wypisujemy te zapytanie na ekran
  10. var_dump( $dbPattern->model );
  11.  
  12. //..dalsza część skryptu...
  13.  


Pytanie czy warto czy nie warto?
Co ważne czy tak przygotowane zapytania były by wygodne w "obróbce", zmianach?
Czy przeciętny PHPMaster wiedział by o co w tym chodzi?
marcio
Przy zapytaniach typu select * from costam where .... order by costam limit 1,10 nie warto przy zlozonych zapytaniach ktore moze miec nawet kilkanascie relacji warto wiem bo ostatnio kolega mi wlasnie pokazal takie rozwiazanie w jego fw spoczatku nie wiedzialem o co biega ale jest to wydajniejsze.










sniver
no właśnie chodzi o złożone zapytania.

Swojego czasu napisałem klase którą przez pewien czas udoskonalałem i dorobiłem pętle, warunki i pare innych drobiazgów.

...ale jakoś nie miałem do czego tego wykorzystać. Planuję ruszyć z kopyta z pewnym projektem i muszę rozwiązać wszystko tak by to było dostępne dla innych programerów...

jeśli by ktoś chciał klase z samplem to pisac na pw
phpion
Cytat(marcio @ 19.11.2009, 14:23:55 ) *
Przy zapytaniach typu select * from costam where .... order by costam limit 1,10 nie warto przy zlozonych zapytaniach ktore moze miec nawet kilkanascie relacji warto wiem bo ostatnio kolega mi wlasnie pokazal takie rozwiazanie w jego fw spoczatku nie wiedzialem o co biega ale jest to wydajniejsze.

O czym Ty mówisz? Twierdzisz, że budując zapytanie w taki sposób (jakimś builderem) wykona się ono szybciej? Przecież i tak finalnie zrobiony z tego zostanie string, który będzie przekazany jako argument do funkcji *_query(). Takie rozwiązanie na pewno nie będzie wydajniejsze; będzie wręcz mniej wydajne.

Ja napisałem sobie klasę, która dynamicznie tworzy mi zapytania (natchnęła mnie do tego klasa z Kohany), ale nie ze względu na wydajność, a dla wygody użytkowania:
  1. $query = new Database_Query_Builder();
  2.  
  3. $query
  4. ->select('*')
  5. ->from('tabela')
  6. ->join('inna', array('inna.tabela_id' => 'tabela.id'))
  7. ->order_by('jakies_pole', 'ASC')
  8. ;
  9.  
  10. if (jakis_warunek) {
  11. $query->where('inne_pole', 10);
  12. }
  13.  
  14. if (inny_warunek) {
  15. $query->where('kolejne_pole', array(1, 2, 3), 'IN');
  16. }

Dzięki dynamicznemu dodawaniu warunków/sortowań/złączeń itd. zdecydowanie wygodniej jest mi w ten sposób tworzyć zapytania.

PS: odszedłem nieco od tematu więc do niego powrócę. Wspomniane przez autora "templatowanie" zapytań to nic innego jako model (w MVC). W modelu zawierasz wszystkie zapytania i masz je w jednym miejscu, a nie porozrzucane po całym systemie.
sniver
Cytat(phpion @ 19.11.2009, 12:42:29 ) *
PS: odszedłem nieco od tematu więc do niego powrócę. Wspomniane przez autora "templatowanie" zapytań to nic innego jako model (w MVC). W modelu zawierasz wszystkie zapytania i masz je w jednym miejscu, a nie porozrzucane po całym systemie.


Dokładnie tak - znam model MVC i wiem na czym polega. Z tym że jestem za extreme programing - a od tego ostatnio się już odeszło i z tego co widzę to wraca się ponownie bo nikt nie ma czasu na tworzenie pięknego kodu smile.gif

...stąd te pytanie, skoro nikt nie ma czasu na ładny kod to trzeba przygotować "zaplecze" tak by całość była odpowiednio poskładana.

oj błogosławieni ci którzy w pracy robią to co chcą haha.gif
marcio
Cytat
O czym Ty mówisz? Twierdzisz, że budując zapytanie w taki sposób (jakimś builderem) wykona się ono szybciej? Przecież i tak finalnie zrobiony z tego zostanie string, który będzie przekazany jako argument do funkcji *_query(). Takie rozwiązanie na pewno nie będzie wydajniejsze; będzie wręcz mniej wydajne.


Query buildera to ja tez uzywam nie chodzi mi o niego, zreszta napewno szybciej zadziala zwykle mysql_query() niz wszystkie te akcje co musi zrobic query builder na stringach i tablicach.

Chodzi o zwykle template'ki dla zapytan sql.

Takie CV dla sql w V trzymamy template zapytanie SQL a za pomoca C wypelniamy tylko potrzebne nam rzeczy jesli czesto mamy takie same zapytanie i zmienie sie tylko warunek where lub nazwa tabeli i kolumn to tak tez sie robi.

sniver
no tak, ale wzorem smarty przetworzone zapytanie może być zapisane jako plik PHP i taki skompilowany plik nie musi być już przetwarzany ponownie do czasu aż skrypt zauważy że we wzorcowym pliku z szablonami zapytań dokonano zmian. Wtedy zaś to przetworzy i zapisze te zapytanie do PHP...

Szybkość tu akurat jest tu istotnym elementem, ale sensownie przemyślane rozwiązanie może być dostępne i na tyle szybkie że nie zabije serwera...
Zyx
Już na wejściu robicie ten sam błąd, co twórcy 98,9% systemów szablonów dla warstwy widoku: udostępniacie ograniczony pozdbiór języka PHP, który będzie do wyrzucenia po napotkaniu pierwszego trudniejszego problemu. Ani to nie będzie przez to bardziej czytelne, ani łatwiejsze w użyciu. Mnożone są niepotrzebnie byty: zapytań SQL w serwisie może być bardzo dużo, nie tworzą one aż tak samodzielnej całości. Z punktu widzenia czytelności kodu lepszym rozwiązaniem jest, aby były one generowane mniej więcej w miejscu wywołania, a nie trzymane gdzieś w zupełnie innym katalogu. Nie wiem, najprawdopodobniej da się stworzyć coś fajnego dla zapytań opartego na szablonach mniej więcej na wzór OPT, by to faktycznie w czymś pomagało, ale w takim kształcie szkoda zachodu. Już obiektowy query builder jest bardziej przydatny, bo przynajmniej operuje się na zapytaniu jak na obiekcie i można go przekazać do jakiegoś innego elementu, by ten go czymś jeszcze obudował... proponuję znaleźć choć jedną funkcjonalną różnicę między poniższymi kodami:

  1. class Model
  2. {
  3. public function pobierzListe($dane)
  4. {
  5. $query = 'SELECT * FROM costam';
  6. if(warunek1)
  7. {
  8. $query .= ' INNER JOIN cos_innego ON costam ';
  9. }
  10.  
  11. if(warunek2)
  12. {
  13. $query .= 'WHERE a = b';
  14. }
  15. return $this->execAndReturn($query);
  16. } // end pobierzListe();
  17. } // end Model;


Od:

Kod
SELECT * FROM costam
{if warunek1}
INNER JOIN cos_innego ON costam
{/if}
{if warunek2}
WHERE a = b
{/if}

+ klasa opakowująca.

Przykład nieco trudniejszy: warunków może być "n", w tym także 0 - wtedy "WHERE" nie powinno być generowane. Taka uproszczona składnia już w tym miejscu albo leży, albo dostajemy gigantycznego ifa z konkatenacją np. 50 warunków, które później są szczegółowo powtarzane.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.