Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Templatowanie zapytań SQL w php
sniver
post
Post #1





Grupa: Zarejestrowani
Postów: 159
Pomógł: 5
Dołączył: 31.08.2007

Ostrzeżenie: (0%)
-----


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?


--------------------
Go to the top of the page
+Quote Post
marcio
post
Post #2





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


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.












--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
Go to the top of the page
+Quote Post
sniver
post
Post #3





Grupa: Zarejestrowani
Postów: 159
Pomógł: 5
Dołączył: 31.08.2007

Ostrzeżenie: (0%)
-----


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


--------------------
Go to the top of the page
+Quote Post
phpion
post
Post #4





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




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.

Ten post edytował phpion 19.11.2009, 12:44:50
Go to the top of the page
+Quote Post
sniver
post
Post #5





Grupa: Zarejestrowani
Postów: 159
Pomógł: 5
Dołączył: 31.08.2007

Ostrzeżenie: (0%)
-----


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


--------------------
Go to the top of the page
+Quote Post
marcio
post
Post #6





Grupa: Zarejestrowani
Postów: 2 291
Pomógł: 156
Dołączył: 23.09.2007
Skąd: ITALY-MILAN

Ostrzeżenie: (10%)
X----


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.



--------------------
Zainteresowania: XML | PHP | MY(SQL)| C# for .NET | PYTHON
http://code.google.com/p/form-builider/
Moj blog
Go to the top of the page
+Quote Post
sniver
post
Post #7





Grupa: Zarejestrowani
Postów: 159
Pomógł: 5
Dołączył: 31.08.2007

Ostrzeżenie: (0%)
-----


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...


--------------------
Go to the top of the page
+Quote Post
Zyx
post
Post #8





Grupa: Zarejestrowani
Postów: 952
Pomógł: 154
Dołączył: 20.01.2007
Skąd: /dev/oracle

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Zyx 19.11.2009, 16:38:38


--------------------
Specjalista ds. głupich i beznadziejnych, Zyx
Nowości wydawnicze: Open Power Collector 3.0.1.0 | Open Power Autoloader 3.0.3.0
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 20.08.2025 - 12:31