[ORM/Criteria] hierarchische result-sets

Pagina: 1
Acties:

  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
Ik ben bezig met Propel, een ORM (object relational mapping)/Persistance layer voor PHP5. Deze is afgeleid van Apache Torque. Ik ben er heel blij mee, maar ik vraag me af of ik er wel helemaal goed mee werk.

Stel, ik heb een tabel 'question', 'answer' en 'client'. Meerdere clients kunnen 1 antwoord geven op 1 vraag. Dus als ik 7 vragen heb en 3 clients, dan heb ik 21 unieke antwoorden. Nou is er een object genaamd Criteria die de database selecties doet:

PHP:
1
2
3
$c = new Criteria();
$c->addJoin(AnswerPeer::QUESTION_ID, QuestionPeer::ID);
$result = QuestionPeer::doSelect($c);


$result bevat Question objecten. In de OOP traditie zou je verwachten dat ik dan ook 7 Questions terug krijg, en als ik voor een Question::getAnswers() zou aanroepen, ik er 3 zou krijgen. Dat laatste werkt ook wel, maar ik krijg in eerste instantie gewoon 21 Questions terug. Is dat normaal in ORM layers als JDO of Torque of wat er ook allemaal is op dat gebied, of doe ik iets fout?

  • EfBe
  • Registratie: Januari 2000
  • Niet online
je krijgt allemaal duplicates terug denk ik, omdat je maar 7 question entities in je db hebt. Door de join krijg je dit:
select question.* from question inner join answers on answer.question_id = question.id
wat duplicates voor question oplevert. Een beetje O/R mapper (ORM is wat anders: http://www.orm.net) filtert die er wel uit. Propel kennelijk niet.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
EfBe schreef op 21 oktober 2004 @ 12:53:
je krijgt allemaal duplicates terug denk ik, omdat je maar 7 question entities in je db hebt. Door de join krijg je dit:
select question.* from question inner join answers on answer.question_id = question.id
wat duplicates voor question oplevert. Een beetje O/R mapper (ORM is wat anders: http://www.orm.net) filtert die er wel uit. Propel kennelijk niet.
Dankjewel! Mijn redenatie klopt dus wel :). Ik heb de vraag ook voorgelegd aan de developers van Propel, kijken wat die er van zeggen. niet zo heel verwonderlijk dat Propel dit (nog) niet kan, het bestaat pas net, en het is an sich natuurlijk al heel cool dat dit soort dingen tegenwoordig kan met PHP5. En dat filteren kan ik natuurlijk zelf ook wel ;).

Bestaat er wel een goede afkorting voor "O/R mapper" dan? Aangezien je er kennelijk wel wat vanaf weet, kun je me misschien ook wel wijzen op een of meer artikelen die O/R mapping in theorie bespreken, zodat ik niet meer van die n00b-vragen hoeft te stellen ;)

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Genoil schreef op 21 oktober 2004 @ 13:57:
Dankjewel! Mijn redenatie klopt dus wel :). Ik heb de vraag ook voorgelegd aan de developers van Propel, kijken wat die er van zeggen. niet zo heel verwonderlijk dat Propel dit (nog) niet kan, het bestaat pas net, en het is an sich natuurlijk al heel cool dat dit soort dingen tegenwoordig kan met PHP5. En dat filteren kan ik natuurlijk zelf ook wel ;).
Het filteren kan op 2 manieren, geen idee of Propel het ondersteunt: je kunt DISTINCT in de query meegenereren, maar dat clasht bij LOB fields, dus indien dat het geval is moet je filteren op de client, wat soms wat lastig kan zijn (compound PK's in een hashtable stoppen e.d.)
Bestaat er wel een goede afkorting voor "O/R mapper" dan? Aangezien je er kennelijk wel wat vanaf weet, kun je me misschien ook wel wijzen op een of meer artikelen die O/R mapping in theorie bespreken, zodat ik niet meer van die n00b-vragen hoeft te stellen ;)
Ik ken geen afkorting ervoor, sommigen gebruiken ORM wat ikzelf niet goed vind want dat is al sinds jaren de afkorting voor Object Role Modelling :). Soms zie je ook O/RM of OR/M.

Het standaardwerk voor O/R mapping is:
http://www.agiledata.org/essays/mappingObjects.html

Echter dat is maar een deel van de koek: want map je entities in de database (het relationele model) op classes of omgekeerd? Het eerste leent zich meer voor lege entities (geen behavior) en manager classes en het laatste leent zich meer voor het domain model.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
met Propel maak je een simpel XML bestandje aan waarmee je
"CREATE TABLE" SQL gegenereerd wordt. Daarnaast worden er een zooi classes gebouwd in de vorm Base{$ClassName} en Base{$Tablename}Peer waar je verder niet aan hoeft te zitten (afgezien van wat bugfixjes :/ ), en {$Tablename} en {$TableName}Peer die daar vanaf stammen om je extra functionaliteit toe te voegen.

Ik heb verder een bijzonder matige achtergrond in OOP/DB-theorie, dus ik weet ook niet wat 'goed' of 'geschikt' is :). Het enige dat ik weet is dat het me veel tijdswinst oplevert, en ondanks dat het nog niet helemaal bugvrije code oplevert, er in ieder geval een stuk minder bugs inzitten en veel meer functionaliteit heeft dan wanneer ik geen OR/M laag zou hebben of zoiets zelf zou proberen te schrijven :)

Het filteren doe ik nou maar met de botte bijl. (Ik ORDER op Question.id)
PHP:
1
2
3
4
5
6
7
8
9
10
        $last_question_id = null;   
        foreach($result as $question) {
            $question_id = $question->getId();
            if($question_id != $last_question_id) {
                $answers = $question->getAnswers();
                ...
                ...
                $last_question_id = $question_id;
            }
        }

[ Voor 3% gewijzigd door Genoil op 21-10-2004 15:26 ]