[OOP] CRUD method's
Zijn we weer terwijl ik werkelijk geen steek verder gekomen ben. Dat komt hoogstwaarschijnlijk omdat ik blijf denken over hoe ik nu alles het beste kan doen. Bedoel het werkt nu allemaal wel en dat is fijn, maar het is niet zoals ik wil.
Ik zou namelijk mijn data op willen slaan via bijvoorbeeld een UserMapper naar een DatabaseStorage de database in. Het klinkt allemaal romantischer dan het is, vooral het lezen. Voornamelijk omdat je zo ongelovelijk veel functies hebt. Neem bijvoorbeeld gewoon een MySql database, ik wil wel gebruik kunnen maken van een eventuele JOIN of DATE functie binnen SQL. Het schrijven en dergelijke lukt me nog wel om een array van te maken en uit te laten voeren. Ik heb alleen geen enkel idee voor de lees functie.
Wat ik nu gebruik
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
public function read($table, $columns, $id)
{
$columns = implode(', ', $columns);
# Query
$sql = "SELECT ".$columns." FROM ".$table;
# Als er een ID is
if( $id != NULL )
{
$sql .= " WHERE id = '".$id;
}
# Query Interpreteren en Controleren door Database
$stmt = $this->db->prepare($sql);
# Query Uitvoeren
$stmt->execute(array((int) $id));
# Result Opvangen en Retouneren d.m.v populate function
while ($result = $stmt->fetch(PDO::FETCH_ASSOC))
{
$data[] = $result;
}
return $data;
}
?>
public function read($table, $columns, $id)
{
$columns = implode(', ', $columns);
# Query
$sql = "SELECT ".$columns." FROM ".$table;
# Als er een ID is
if( $id != NULL )
{
$sql .= " WHERE id = '".$id;
}
# Query Interpreteren en Controleren door Database
$stmt = $this->db->prepare($sql);
# Query Uitvoeren
$stmt->execute(array((int) $id));
# Result Opvangen en Retouneren d.m.v populate function
while ($result = $stmt->fetch(PDO::FETCH_ASSOC))
{
$data[] = $result;
}
return $data;
}
?>
Zoals je ziet kan ik dan alleen niet JOINEN. Moet ik het zoeken bij een multidimensionale array? Moet ik meerdere methods gaan maken welke dan bijvoorbeeld de MySql functies representeren? Waar zit jullie gedachte hierbij? Dat laatste haalt alleen ook weer functionaliteit weg lijkt mij?
Vind het lastige keuzes waar ik al tijden mee aan het stoeien ben.
Vervolgens kan je je afvragen wat het nut is van een algemene class/methode die op basis van algemene instructies een query opbouwt. Uiteindelijk is elke query nog altijd uniek (tot op zekere hogere aangezien je de SELECT * FROM tabel queries alleen bij beginners tegenkomt) en dus zal je linksom of rechtsom ergens in je code die query moeten opbouwen. Wil je dat via allerlei abstracte instructies, of gewoon direct in tekst? Ik heb altijd voor het laatste gekozen, dus gewoon uiteindelijk elke query in een string uitgeschreven in je code. In elk geval kan je altijd elke query bouwen en het maakt het allejezus veel makkelijker om het ook nog eens te testen.
Kies je voor de abstracte querybuilder ga je dan eens alle mogelijke verschillende opties voorstellen. Een klein voorbeeldje:
- aggregate functies
- joins
- joins met meerdere voorwaarden
- subqueries
- virtuele tabellen
- virtuele kolommen
- group concats
- having clause
- group by
Kan het? Ja vast, is je code dan nog leesbaar en is het sneller (wat code bouwen betreft), ik betwijfel het ten zeerste.
Of gebruik bijv. gewoon de Doctrine Query Builder.
Ik denk nu even hardop en ga meteen zeggen dat dat weer niet goed is want dat zou betekenen dat bijvoorbeeld een read method 2 taken krijgt, wat dus eigenlijk niet de bedoeling is.
Wouter, ik heb momenteel het gevoel dat ik nog niet toe ben aan al het importeren van soort systemen. Ik ben nog lang niet bekwaam genoeg om ook dat te gaan begrijpen. Althans zo voel ik het.
Gewijzigd op 07/02/2014 17:27:54 door Milo S
Quote:
Ik ben nog lang niet bekwaam genoeg om ook dat te gaan begrijpen. Althans zo voel ik het.
Dan is het tijd van dat gevoel af te stappen. Je bent het wel! :)
Het gebruik van dat soort tools leert je juist hoe dit soort problemen worden opgelost.
Ze worden ook het vaakst gebruikt door mensen die zelf geen query kunnen uitschrijven, en die komen dan in de problemen wanneer van het abstracte afgeweken moet worden.
Wouter J op 07/02/2014 17:28:48:
Dan is het tijd van dat gevoel af te stappen. Je bent het wel! :)
Het gebruik van dat soort tools leert je juist hoe dit soort problemen worden opgelost.
Quote:
Ik ben nog lang niet bekwaam genoeg om ook dat te gaan begrijpen. Althans zo voel ik het.
Dan is het tijd van dat gevoel af te stappen. Je bent het wel! :)
Het gebruik van dat soort tools leert je juist hoe dit soort problemen worden opgelost.
En mogelijk nog belangrijker, je leert door trial and error ook hoe/wanneer je tools niet moet gebruiken. Dat helpt in de toekomst weer de beste tool for the job te kiezen.
Oké, maar als iemand mij uit kan leggen wat nu het voordeel is van een query builder....
En de Doctrine qb heeft een oplossing voor het niet alles implementeren van query elementen. Je kan namelijk ook de ->add() functie gebruiken om een custom stukje in de query te stoppen.
Of tien functies aanroepen om één query te bouwen.
Nog steeds geen voordeel
Iedereen zijn eigen mening Ger...
Das wel heel erg makkelijk Wouter.
Aan de andere kant wat ik zo zag van die Query Builder vindt ik dat er toch wel chiq uitzien.. Of het praktisch is weet ik zo net nog niet.
Vandaar dat ik het eerst eens gewoon ga proberen zoals Erwin voorstelde. Bij wijs van spreken kan ik altijd nog zeggen dat ik die Dictrine Query Builder wil, het is dan iets meer werk, maar ik heb dan het gevoel alsof het allemaal wat rustiger gaat.
Ik ga nu dus voor een DataMapper en in dit geval een DatabaseStorage. In de DataMapper heb ik mijn query die de resultaten door de DatabaseStorage laat ophalen en die in een array dumpt.
Bedankt voor alle adviezen jongens hier kan ik wat mee in mijn weg naar het onbekende...
Doctrine:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
// $qb instanceof QueryBuilder
// example8: QueryBuilder port of: "SELECT u FROM User u WHERE u.id = ? OR u.nickname LIKE ? ORDER BY u.surname DESC" using Expr class
$qb->add('select', new Expr\Select(array('u')))
->add('from', new Expr\From('User', 'u'))
->add('where', $qb->expr()->orX(
$qb->expr()->eq('u.id', '?1'),
$qb->expr()->like('u.nickname', '?2')
))
->add('orderBy', new Expr\OrderBy('u.name', 'ASC'));
?>
// $qb instanceof QueryBuilder
// example8: QueryBuilder port of: "SELECT u FROM User u WHERE u.id = ? OR u.nickname LIKE ? ORDER BY u.surname DESC" using Expr class
$qb->add('select', new Expr\Select(array('u')))
->add('from', new Expr\From('User', 'u'))
->add('where', $qb->expr()->orX(
$qb->expr()->eq('u.id', '?1'),
$qb->expr()->like('u.nickname', '?2')
))
->add('orderBy', new Expr\OrderBy('u.name', 'ASC'));
?>
Als dit als resultaat de query in het comment oplevert is het tijd om die query builder linea recta naar het ronde archief te verplaatsen.
Gewijzigd op 08/02/2014 19:42:16 door Ger van Steenderen
Milo S op 08/02/2014 11:33:13:
Vandaar dat ik het eerst eens gewoon ga proberen zoals Erwin voorstelde. Bij wijs van spreken kan ik altijd nog zeggen dat ik die Dictrine Query Builder wil, het is dan iets meer werk, maar ik heb dan het gevoel alsof het allemaal wat rustiger gaat.
Even los van hoe het het beste is (meningen zijn verdeeld zoals altijd), als je het goed doet (lees: OOP) dan maakt het uiteindelijk niet zoveel uit. Wat je wil is een class die je kan aanroepen om je de query terug te geven die je nodig hebt. Zolang je die structuur goed opzet kan je er nu voor kiezen om het nog even heel simpel te houden en gewoon in die class alle queries uit te schrijven. Later kan je er een andere class voor in de plaats zetten waarin je bijvoorbeeld wel een query builder gebruikt. Of misschien haal je het dan wel weer uit allerlei include bestanden of....
Nou ja, de kracht van OOP dus. Zorg dat je die structuur goed hebt dan kan je op elk moment nog besluiten om het op de ene of de andere manier te doen.
Gewijzigd op 08/02/2014 19:58:36 door Erwin H
Of je bent nu aan het extreem aan het overdrijven om een paar overduidelijke documentatie foutjes, of ik begrijp je bericht niet...
Gewijzigd op 08/02/2014 20:21:25 door Wouter J
Als je voor een simpele query als in het voorbeeld van Doctrine, 10 functies moeten worden uitgevoerd om alleen een zeer simpele string te maken ....
Heeft niks met programmeren te maken.
Gewijzigd op 08/02/2014 20:21:56 door Erwin H
Offtopic:
Eigenlijk ben ik altijd nog erger en gebruik ik gewoon de ODM van doctrine, hoef ik helemaal geen query meer te typen...
Edit:
Documentatie is gefixed: https://github.com/doctrine/doctrine2/pull/940 :)
Gewijzigd op 08/02/2014 20:37:03 door Wouter J
Was overigens ook niet bedoelt om doctrine af te kraken, want ik heb alle respect voor hoe het geprogammeerd is.
Ik vind het alleen overkill.
Ik heb in code igniter (active record) alle functies die met een select query te maken hebben eruit gesloopt.
Gewijzigd op 08/02/2014 21:00:50 door Ger van Steenderen
Klinkt dit als een plan?