Beste mensen,
Al een tijdje heb ik een probleem waar ik niet uit kom.
Dit betreft het ontwerpen van een methode om data uit een database op te slaan in classes, de data in de classes aan te passen en vervolgens weer op te slaan.
zie het zo:
ik heb een tabel (laten ze zeggen persoon) met wat velden (id (PK), naam, bsn nummer etc.)
nu kan ik een class maken die dezelfde velden heeft (eventueel laten genereren adhv de tabel), en deze middels een query vullen.
dan heb je een 1op1 van de tabel als class. Een record is dan een instantie van die class, en wanneer je
Persoon p = new Persoon(1) doet krijg je bijvoorbeeld een nieuwe instantie van het eerste record uit die tabel.
p.Save() slaat het record dan weer op.
tot zover is er niks aan de hand.
echter, stel nou dat ik twee tabellen heb, 'persoon' (zie hierboven) en bijvoorbeeld 'order' (id, persoonid, totaalbedrag, etc.)
Nu wil ik een lijst hebben met alle orders, en de naam van de persoon erbij.
Geen probleem zou je zeggen, dat wordt zoiets:
[sql]
SELECT `o`.*, `p`.naam`
FROM `order` AS `o`
INNER JOIN `persoon` AS `p` ON `o`.`persoonid` = `p`.`id`
[/]
echter.. in welke klasse ga je dat resultaat opslaan?
je hebt er geen klasse voor...
Nu zijn er een aantal dingen waar ik aan dacht, maar geen enkel idee lijkt compleet te werken.
echter, je hebt dan geen idee meer welke persoon er bij welke order hoort, en dus zul je ze moeten koppelen.
laten we zeggen de simpelste methode om dat te doen, is een tweedimentionale collectie van wat voor soort dan ook.
dus :
echter, waar ga je die collectie opslaan, en hoe ga je ervoor zorgen dat de data die je hebt ook weer terug opgeslagen kan worden?
stel dat ik de naam van een persoon verander, en ik wil mijn persoon instantie opslaan, dan weet ik niet welk ID (de pk) mijn persoon heeft.
Enige manier om dit lekker te laten werken is dus van alle tabellen (ook in joins) altijd alle velden opvragen (of in ieder geval altijd de PK) en een inteligent systeem te maken dat aan de hand van een query weet welke velden er uit welke tabel komen.
dus dat je weet dat de eerste velden (tot de tweede 'id' kolom die je tegenkomt) bij de eerste tabel horen, vanaf de tweede id kolom tot de 3de bij de tweede tabel etc.
echter heb ik dan nog steeds geen idee hoe ik op een nette manier mijn koppeling tussen instanties van de klasses moet bewaren. (dus welke persoon aan welke order zit)
ik zou dan geen klasses hoeven genereren (of overtypen) en heb dus geen 1op1 relatie met een tabel.
Ik zou dan het hierboven beschreven probleem kunnen oplossen door een instantie te maken van die klasse (laten we hem 'QueryResult' noemen) en deze instantie de result te geven van een query.
ik zie de klasse dat een beetje zo voor me:
QueryResult
- record[]
- nrOfRows
- Original Query
- Execution time
- etc.
waarbij 'record' weer een collectie is van een andere class is die er ongeveer zo uit ziet:
Record
- tablename
- columnname
- value
Op deze manier kan je dus onze mooie join uitvoeren, en het resultaat in die objecten stoppen.
Echter ook hier zit weer een probleem aan dat ik niet helemaal kan oplossen.
Ten eerste heb je een slimme methode nodig om de tablename en de columnname op te vragen.
Bij een select * heb je namelijk aan de hand van je query geen enkel idee welke kolommen je opvraagd.
Echter, elk DBMS (dat je wilt gebruiken tenminste) retourneerd wel op de een of andere manier de opgevraagde kolommen.
Wanneer je dan data wijzigd in je klasse is het dus goed te doen om in je .Save() een methode te maken die adhv de tablename en columnname een update query uitvoert.
Echter, wat als je een nieuwe instantie wilt maken van een bepaald object, laten we zeggen 'persoon'
Ik kan in de tablename wel 'persoon' invullen, maar zou dit dan al uit me hoofd doen. Er is geen controlle of die 'persoon' tabel eigenlijk wel bestaat. Ditzelfde geld voor de kolommen. En de value's die je er in duwt kunnen van een compleet andere datatype zijn...
Natuurlijk valt dit met een aantal queries wel te controlleren, maar wanneer je dan veel nieuwe objecten aanmaakt blijf je queries schieten op de DB.
Verder is het zo dat je geen eigen methodes die specifiek voor die klasse zijn kunt toevoegen aan de klasse.
Stel dat ik een methode heb om uit te rekenen of een bepaalde persoon wel ouder is dan een bepaalde leeftijd, dan zou ik dit normaal in de Persoon klasse doen.
dus
Alleen heb ik geen Persoon klasse....
Erg lastig dus.
Weet een van jullie misschien een manier om te zorgen dat ik op een fatsoenlijke manier toch dit soort dingen kan doen?
Is er misschien een standaard oplossing voor?
hebben jullie zelf oplossingen?
oplossingen voor de problemen in mijn oplossingen? (
)
deel het
Al een tijdje heb ik een probleem waar ik niet uit kom.
Dit betreft het ontwerpen van een methode om data uit een database op te slaan in classes, de data in de classes aan te passen en vervolgens weer op te slaan.
zie het zo:
ik heb een tabel (laten ze zeggen persoon) met wat velden (id (PK), naam, bsn nummer etc.)
nu kan ik een class maken die dezelfde velden heeft (eventueel laten genereren adhv de tabel), en deze middels een query vullen.
dan heb je een 1op1 van de tabel als class. Een record is dan een instantie van die class, en wanneer je
Persoon p = new Persoon(1) doet krijg je bijvoorbeeld een nieuwe instantie van het eerste record uit die tabel.
p.Save() slaat het record dan weer op.
tot zover is er niks aan de hand.
echter, stel nou dat ik twee tabellen heb, 'persoon' (zie hierboven) en bijvoorbeeld 'order' (id, persoonid, totaalbedrag, etc.)
Nu wil ik een lijst hebben met alle orders, en de naam van de persoon erbij.
Geen probleem zou je zeggen, dat wordt zoiets:
[sql]
SELECT `o`.*, `p`.naam`
FROM `order` AS `o`
INNER JOIN `persoon` AS `p` ON `o`.`persoonid` = `p`.`id`
[/]
echter.. in welke klasse ga je dat resultaat opslaan?
je hebt er geen klasse voor...
Nu zijn er een aantal dingen waar ik aan dacht, maar geen enkel idee lijkt compleet te werken.
oplossing 1
je maakt twee instanties van de twee klasses die je hebt (persoon en order) met daarin de waardes die je opgevraagd hebt.echter, je hebt dan geen idee meer welke persoon er bij welke order hoort, en dus zul je ze moeten koppelen.
laten we zeggen de simpelste methode om dat te doen, is een tweedimentionale collectie van wat voor soort dan ook.
dus :
code:
1
2
3
4
| [0][0] -> order1 [0][1] -> persoon1 [1][0] -> order2 [1][1] -> persoon2 |
echter, waar ga je die collectie opslaan, en hoe ga je ervoor zorgen dat de data die je hebt ook weer terug opgeslagen kan worden?
stel dat ik de naam van een persoon verander, en ik wil mijn persoon instantie opslaan, dan weet ik niet welk ID (de pk) mijn persoon heeft.
Enige manier om dit lekker te laten werken is dus van alle tabellen (ook in joins) altijd alle velden opvragen (of in ieder geval altijd de PK) en een inteligent systeem te maken dat aan de hand van een query weet welke velden er uit welke tabel komen.
dus dat je weet dat de eerste velden (tot de tweede 'id' kolom die je tegenkomt) bij de eerste tabel horen, vanaf de tweede id kolom tot de 3de bij de tweede tabel etc.
echter heb ik dan nog steeds geen idee hoe ik op een nette manier mijn koppeling tussen instanties van de klasses moet bewaren. (dus welke persoon aan welke order zit)
oplossing 2
Stel nou dat ik in plaats van allemaal 1op1 klasses te maken van tabellen gewoon zeg dat ik 1 klasse heb die in staat is om data uit allerlei tabellen op te slaan.ik zou dan geen klasses hoeven genereren (of overtypen) en heb dus geen 1op1 relatie met een tabel.
Ik zou dan het hierboven beschreven probleem kunnen oplossen door een instantie te maken van die klasse (laten we hem 'QueryResult' noemen) en deze instantie de result te geven van een query.
ik zie de klasse dat een beetje zo voor me:
QueryResult
- record[]
- nrOfRows
- Original Query
- Execution time
- etc.
waarbij 'record' weer een collectie is van een andere class is die er ongeveer zo uit ziet:
Record
- tablename
- columnname
- value
Op deze manier kan je dus onze mooie join uitvoeren, en het resultaat in die objecten stoppen.
Echter ook hier zit weer een probleem aan dat ik niet helemaal kan oplossen.
Ten eerste heb je een slimme methode nodig om de tablename en de columnname op te vragen.
Bij een select * heb je namelijk aan de hand van je query geen enkel idee welke kolommen je opvraagd.
Echter, elk DBMS (dat je wilt gebruiken tenminste) retourneerd wel op de een of andere manier de opgevraagde kolommen.
Wanneer je dan data wijzigd in je klasse is het dus goed te doen om in je .Save() een methode te maken die adhv de tablename en columnname een update query uitvoert.
Echter, wat als je een nieuwe instantie wilt maken van een bepaald object, laten we zeggen 'persoon'
Ik kan in de tablename wel 'persoon' invullen, maar zou dit dan al uit me hoofd doen. Er is geen controlle of die 'persoon' tabel eigenlijk wel bestaat. Ditzelfde geld voor de kolommen. En de value's die je er in duwt kunnen van een compleet andere datatype zijn...
Natuurlijk valt dit met een aantal queries wel te controlleren, maar wanneer je dan veel nieuwe objecten aanmaakt blijf je queries schieten op de DB.
Verder is het zo dat je geen eigen methodes die specifiek voor die klasse zijn kunt toevoegen aan de klasse.
Stel dat ik een methode heb om uit te rekenen of een bepaalde persoon wel ouder is dan een bepaalde leeftijd, dan zou ik dit normaal in de Persoon klasse doen.
dus
code:
1
| if (Persoon.CheckAge(16)) { /* do stuff */ } |
Alleen heb ik geen Persoon klasse....
Erg lastig dus.
Weet een van jullie misschien een manier om te zorgen dat ik op een fatsoenlijke manier toch dit soort dingen kan doen?
Is er misschien een standaard oplossing voor?
hebben jullie zelf oplossingen?
oplossingen voor de problemen in mijn oplossingen? (
deel het
This message was sent on 100% recyclable electrons.