Objekt-relationales Mapping

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Objekt-relationales Mapping

    Servus,
    ich stehe vor folgemdem Problem. Ich plane an einem Projekt, das ich über das Mojavi-MVC-Framework (http://www.mojavi.org) realisieren will.

    Die eigentliche Problemstellung ist die Abbildung der Tabellenstruktur in Klassen. Nehmen wir man an ich habe eine Tabelle "Schulklasse", die eine 1-n Relation zur Tabelle "Schüler" enthält.
    EDIT:

    Schulklasse
    -----------
    id
    name

    Schüler
    -------
    id
    schulklasse_id
    name
    ...




    Dafür benötige ich nach der Theorie nach ja nun 2 Klassen "Schulklasse" und eben wieder "Schüler". Beide haben zum Beispiel eine Methode "load()", die den entsprechenden Datensatz anhand der "id" aus der jeweiligen Tabelle holt.

    Wenn ich jetzt einen Schüler anzeigen will, verwende ich folgenden Pseudo-Code:

    EDIT:
    Schueler::load(12);




    Wenn ich jetzt aber alle Schüler ausgeben will, die einer Schulklasse angehören - dann muss ja die Klasse "Schulklasse" eine Liste (Array) von "Schüler" enthalten. Rein nach der MVC-Lehre nach muss ja nun "Schulklasse" x-Mal die load-Methode von "Schüler" aufgerufen werden, was jedesmal eine neue Datenbankverbindung bedeutet:

    EDIT:
    SELECT * FROM schueler WHERE id=xyz



    Performancemäßig bei mehreren Datensätze ja eine Katastrophe. Besser wäre ja eine Abfrage:

    EDIT:
    SELECT * FROM schueler WHERE schulklasse_id=xyz




    Noch besser wäre natürlich folgende Abfrage, damit zusätzlich zusammen gleich die Daten der Schulkasse geladen werden:

    EDIT:
    SELECT * FROM schuklasse LEFT JOIN schueler...



    Auf die Schnelle würde ich diese Abfrage irgendwo in einer Methode in "Schulklasse" unterbringen und die geladenen Datensätze dann irgendwie wieder in einer "Schüler"-Liste speichern. Aber das würde ja dann die MVC-Lehre etwas durchbrechen.

    Ich weiss dass es OR-Mapping-Klassen gibt, habe aber in PHP noch nichts gefunden, bzw. entsprechende Doku dazu. Wie bildet man so ein Problem nun am besten (Performance und Lehre) ab? Vorallem wenn es dann auch mal JOINS über mehrere Tabellen geben soll.

    gruss Markus
    Simploo CMS - das einfache Webseiten-Bearbeitungsprogramm

  • #2
    Ich würde wahrscheinlich die Schülerklasse so aufbauen, dass eine Instanz zur Verwaltung der Daten ausreicht. Durch die Methode Student::next() wird bei mehreren Benutzern zum nächsten Schüler gesprungen. Somit hast du den Vorteil, dass nur eine Student Instanz benötigt wird und nur eine Datenbank abfrage gestellt werden muss. Dieses Iterator Prinzip findest du z.B. auch in WACT http://wact.sourceforge.net.
    PHP-Code:
    <?php

    class Student

    {
        var 
    $class;
        var 
    $name;
        
    //...
        
    var $db;
        
        function 
    student(&$db)
        {
            
    $this->db =& $db;
        }
        
        
        function 
    getName() {}
        function 
    getClass() {}
        function 
    setName($name) {}
        function 
    setClass($class) {}
        
        function 
    loadByID($id) {}
        function 
    loadByName($name) {}
        function 
    loadByClass($class) {}
        
        function 
    reset() {}
        function 
    next() {}    
    }

    // Verwendung
    $student = new Student($db);
    $student->loadByClass('g02');

    while(
    $student->next()) {
        echo 
    $student->getName() . "<br>\n";
    }
    ?>
    Zuletzt geändert von webstar85; 26.05.2004, 18:28.

    Kommentar


    • #3
      Ich stehe gerade vor dem gleichem Problem, verstehe aber nicht, wie die Funktionen next() und reset() aussehen müssen oder, wofür sie da sind. Und wo wird der das Ergebnis loadbyClass() gespeichert? In einer Membervariable? Sonst finde ich diesen Ansatz ziemlich benutzbar

      Kommentar


      • #4
        Oder kennt jemand andere offene (Mini-)Projekte, wo ich mich lesend weiterbilden kann?

        Kommentar


        • #5
          Niemand?

          Kommentar


          • #6
            Original geschrieben von Realmaker
            Ich stehe gerade vor dem gleichem Problem, verstehe aber nicht, wie die Funktionen next() und reset() aussehen müssen oder, wofür sie da sind. Und wo wird der das Ergebnis loadbyClass() gespeichert? In einer Membervariable? Sonst finde ich diesen Ansatz ziemlich benutzbar
            Die Funktion next() dient in diesem Beispiel dafür den nächsten Datensatz der Abfrage auszulesen und dem Objekt zuzuweisen. Die Werte können entweder in einem einzigen Array oder in die entsprechenden Objektvariablen gespeichert werden, wie angedeutet. Dabei gibt i]next()[/i] einen Wahrheitswert zurück, ob es einen nächsten Datensatz gibt.

            i]reset()[/i] wird dafür benötigt, wenn man die gleiche Abfrage nochmal ausführen will. Also muss der Query String noch einmal aufgerufen werden.

            Um es anschaulicher zu machen, hier ein (unvollständiges) Beispiel:
            PHP-Code:
            var $query;

            function 
            fetchByClass($class)
            {
                
            $this->query 'SELECT * FROM STUDENTS WHERE classID =  ' intval($class);
                
            $this->db->query($this->query);
            }

            function 
            next()
            {
                
            $result $this->db->fetchArray();

                if(!
            is_array(($result) || (count($array) == 0)) {
                    return 
            false;
               }

                
            $this->name $result['name'];
                
            $this->class $result['class'];
                
            // ...

               
            return true;
            }

            function 
            reset()
            {
                  
            $this->db->query($this->query);

            Kommentar


            • #7
              Aaaahhh... danke

              Kommentar


              • #8
                Trotzdem würde es mich interessieren, was andere zu diesem Ansatz sagen.

                Kommentar


                • #9
                  Ich glaube nicht das du das wirklich wissen willst .. !
                  carpe noctem

                  [color=blue]Bitte keine Fragen per EMail ... im Forum haben alle was davon ... und ich beantworte EMail-Fragen von Foren-Mitgliedern in der Regel eh nicht![/color]
                  [color=red]Hinweis: Ich bin weder Mitglied noch Angestellter von ebiz-consult! Alles was ich hier von mir gebe tue ich in eigener Verantwortung![/color]

                  Kommentar


                  • #10
                    Doch will ich, auch wenn du eine ganz andere Meinung dazu hast.

                    Kommentar


                    • #11
                      @Goth:
                      Sorry, nichts gegen dich - aber auf solche Beiträge könnte ich in Foren echt verzichten. Entweder man sagt etwas konstruktives (egal ob positiv oder negativ) zum Thema oder man läßt es bleiben.

                      Aber mit dieser Aussage hilfst du nun wirklich niemand. Mich interessiert es wirklich, wie man Relationale Datenbanken am besten in Objekten/Klassen abbildet - und das natürlich PHP-praktikabel.

                      gruss Markus
                      Simploo CMS - das einfache Webseiten-Bearbeitungsprogramm

                      Kommentar


                      • #12
                        Original geschrieben von eintrachtemil
                        @Goth:
                        Sorry, nichts gegen dich - aber auf solche Beiträge könnte ich in Foren echt verzichten. Entweder man sagt etwas konstruktives (egal ob positiv oder negativ) zum Thema oder man läßt es bleiben.

                        Aber mit dieser Aussage hilfst du nun wirklich niemand. Mich interessiert es wirklich, wie man Relationale Datenbanken am besten in Objekten/Klassen abbildet - und das natürlich PHP-praktikabel.

                        gruss Markus
                        Auf was Du verzichten kannst oder nicht ist mir vollkommen wurst ... mein Kommentar bezog sich rein auf das Posting von Realmaker ... und geht Dich einen feuchten Scheissdreck an ...

                        Ich persönlich halte den Klassen-Entwurf für vollkommenen Tinnef, weil er ein vollkommen absurdes Verständnis des OO-Modells vermuten läßt ...

                        ... also ... halt lieber den Sabbel wenn sich Erwachsene unterhalten ... !
                        carpe noctem

                        [color=blue]Bitte keine Fragen per EMail ... im Forum haben alle was davon ... und ich beantworte EMail-Fragen von Foren-Mitgliedern in der Regel eh nicht![/color]
                        [color=red]Hinweis: Ich bin weder Mitglied noch Angestellter von ebiz-consult! Alles was ich hier von mir gebe tue ich in eigener Verantwortung![/color]

                        Kommentar


                        • #13
                          Wie wäre es dann, wenn du schreiben würdes, wie ein Klassen-Entwurf aussehen würde den du bevorzugen würdest?
                          Simploo CMS - das einfache Webseiten-Bearbeitungsprogramm

                          Kommentar


                          • #14
                            Letztlich gibt's 2 Aspekte ... zum einen den einen vernünftigen OO-Ansatz ... zum anderen Performance.

                            Zu einem vernünftigen OO-Ansatz gehört es das man Org. Einheiten erkennt und solche entsprechend abbildet ... das heisst ihnen die Eigenschaften und Aktionen (Methoden) zuordnet ... und zwar nur diese ... somit kann zwar ein Schüler dem anderen von meinetwegen eine runterhauen aber er kann sich auf keinen Fall in einen anderen Schüler verwandeln ... !

                            Auf der anderen Seite haben wir die Klasse "Schulklasse" diese verwaltet den "Klassenverband" ... und aus diesem Grunde sollte sie auch sämtliche Aktionen bekommen die mit seiner Verwaltung einhergehen ...

                            Letztlich liegt bei einer vernünftigen Programmiersprache die Lösung, für den Performance Ansatz, in einer Überladung des Constructors der Klasse "Schüler" (übergabe einer ID oder der Schülerdaten) ... in PHP könnte man sich damit behelfen das man entweder eine numerische ID oder ein Array mit Daten übergibt. Soll heissen: Die Klasse "Schulklasse" läd' im Constructor (oder meinetwegen auch in einer Methode) die Daten der Schüler aus der DB und übergibt zur Initialisierung den jeweiligen DS an die Schülerklasse.

                            Beispiel:
                            PHP-Code:
                            class cSchueler {

                            var 
                            $name "";
                            var 
                            $klassensprecher FALSE;
                            var 
                            $beulen 0;

                            function 
                            cSchueler($init) {
                                if ( 
                            is_array($init) ) {
                                    
                            $this->fetchData($init);
                                } else {
                                    if ( 
                            $res mysql_query("SELECT * FROM schueler WHERE id = '".mysql_real_escape_string($id)."'") ) {
                                        if ( 
                            $row mysql_fetch_array($res) ) {
                                            
                            $this->fetchData($init);
                                        } else die(
                            "FEHLER");
                                        
                            mysql_free_result($res);
                                    } else die(
                            "FEHLER");
                                }
                            }

                            function 
                            fetchData($id) {
                                
                            $this->name $init["name"];
                                
                            $this->klassensprecher = (boolean)$init["klassesprecher"];
                                
                            $this->beulen $init["beulen"];
                            }

                            function 
                            hautRunter(&$schueler) {
                                
                            $schueler->beulen++;
                            }

                            }

                            class 
                            cSchulklasse {
                                
                            var 
                            $schueler = array();

                            function 
                            cSchulklasse($id) {
                                ...
                                if ( 
                            $res mysql_query("SELECT * FROM schueler WHERE classID = '".mysql_real_escape_string($id)."'") ) {
                                    while ( 
                            $row mysql_fetch_array($res) ) {
                                        
                            $this->schueler[] = new cSchueler($row);
                                    }
                                    
                            mysql_free_result($res);
                                } else die(
                            "FEHLER");
                                ...
                            }

                            }

                            $klasse = new cSchulklasse("10A"); 
                            Für einen wirklich ordentlichen OO-Ansatz ist die performance zunächstmal nebensächlich. Da es bei der OO primär um eine Modellierung also abbildung von (virtuellen) Realitäten geht ...
                            Zuletzt geändert von goth; 01.06.2004, 17:01.
                            carpe noctem

                            [color=blue]Bitte keine Fragen per EMail ... im Forum haben alle was davon ... und ich beantworte EMail-Fragen von Foren-Mitgliedern in der Regel eh nicht![/color]
                            [color=red]Hinweis: Ich bin weder Mitglied noch Angestellter von ebiz-consult! Alles was ich hier von mir gebe tue ich in eigener Verantwortung![/color]

                            Kommentar


                            • #15
                              Original geschrieben von goth
                              Ich persönlich halte den Klassen-Entwurf für vollkommenen Tinnef, weil er ein vollkommen absurdes Verständnis des OO-Modells vermuten läßt ...
                              Da fragt sich nur, wie du es machen würdest. Einfach hinschreiben, dass man es nicht für gut hält können viele, einen konstruktiven Beitrag geben fällt einigen hier schwer.

                              Ich gebe zu, dass man meinen Vorschlag noch optimieren könnte / sollte. Dieser könnte z.B. so aussehen:

                              PHP-Code:
                              <?php


                              class Student

                              {
                                  var 
                              $params;
                                  /...
                                  
                                  function 
                              student($student=array())
                                  {
                                      
                              $this->params $student;
                                  }
                                  
                                  function 
                              import($student)
                                  {
                                      
                              $this->params $student;
                                  }
                                  
                                  function 
                              getName() {}
                                  function 
                              getClass() {}
                                  function 
                              setName($name) {}
                                  function 
                              setClass($class) {}
                              }


                              class 
                              StudentFinder
                              {
                                  var 
                              $db;
                                  var 
                              $query;
                                  var 
                              $student;
                                  
                                  function 
                              StudentFinder(&$db, &$student)
                                  {
                                      
                              $this->db =& $db;
                                      
                              $this->student =& $student;
                                  }
                                  
                                  function 
                              findByID($id) {
                                  }
                                  function 
                              findByName($name) {}
                                  function 
                              findByClass($class)
                                  {
                                      
                              $this->query 'SELECT * FROM STUDENTS WHERE classID =  ' intval($class);
                                      
                              $this->db->query($this->query);
                                  }
                                  
                                  function 
                              reset()
                                  {
                                      
                              $this->db->query($this->query);
                                  }
                                  
                                  function 
                              next()
                                  {
                                      
                              $result $this->db->fetchArray();

                                      if(!
                              is_array(($result) || (count($array) == 0)) {
                                              return 
                              false;
                                      }
                                      
                                      
                              $this->student->import($result);
                                      
                              // ...

                                      
                              return true;
                                  
                                  }
                              }


                              // Anwendungsbeispiel:
                              $student = new Student();
                              $db = new MySQLConnection();

                              $finder = new StudentFinder($db$student);
                              $finder->findByClass('2');

                              // $student wird aktualisiert, da es per reference übergeben wird
                              while($finder->next()) {
                                  echo 
                              $student->getName() . '<br>';
                              }
                              ?>
                              Zwei interesannte Links zu diesem Thema:
                              http://www.phppatterns.com/index.php...leview/25/1/1/
                              http://www.sitepoint.com/forums/showthread.php?t=172470

                              Kommentar

                              Lädt...
                              X