Ankündigung

Einklappen
Keine Ankündigung bisher.

Datenbankabfragen auslagern

Einklappen

Neue Werbung 2019

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

  • Datenbankabfragen auslagern

    Hallo zusammen,

    ich habe mein Problem bereits in der Contao-Community geschildert, allerdings kann mir dort niemand so recht helfen. Und da es sowieso weniger ein Contao spezifisches Problem, sondern eher eine Designfrage ist, versuche ich es hier

    Contao-Extensions bestehen i.d.R. aus einer Klasse, in denen bis auf die View alles zusammengewürfelt wird.
    Ich arbeite nun an einer Schnittstelle zu einer komplexen Datenbank, für die die MySQL-Abfragen entsprechend umfangreich sind. Damit der Code übersichtlich bleibt suche ich nun nach einer Möglichkeit, die Abfragen auszulagern.

    Ich habe mir überlegt, für jede Gruppe von Abfragen ein eigenes Model zu schreiben. Z.B. alle Abfragen betreffend Dokumente/Downloads werden in einer Klasse DownloadsModel gesammelt. Analog alles was mit Kontakten zu tun hat in einer ContactsModel usw.
    Irgendwie habe ich aber damit das Gefühl, dass es bis auf die Umsetzung nicht mehr viel mit OOP zu tun hat. Bin daher für jegliche Vorschläge/Anregungen/Ideen dankbar

    Beispiel-Model:
    PHP-Code:
    class DownloadModel extends Model 


        
    /** 
         * Connect to crm database 
         */ 
        
    public function connect() 
        { 
            
    $this->Database->setDatabase($GLOBALS['TL_CONFIG']['crmDbDatabase']); 
            
    $this->Database->execute("SET NAMES 'utf8'");                 
        } 
         
        
    /** 
         * Disconnect from crm database 
         */ 
        
    public function disconnect() 
        { 
            
    $this->Database->setDatabase($GLOBALS['TL_CONFIG']['dbDatabase']); 
            
    $this->Database->execute("SET NAMES 'utf8'"); 
        } 
         
        
    /** 
         * Sample method 
         */ 
        
    public function getProducts($params
        { 
            
    $sql "SQL"
            return 
    $this->Database->execute($sql); 
        } 


    Extension:
    PHP-Code:
    // Import model 
    $this->import('DownloadModel'); 

    // Switch database to crm 
    $this->DownloadModel->connect(); 
    // Sample query 
    $objResult $this->DownloadModel->getProducts($params); 
    // Switch database back to contao 
    $this->DownloadModel->disconnect(); 

    print_r($objResult); 
    Die Methoden connect() und disconnect() würde ich in die Elternklasse auslagern, damit die nicht in jeder Modelklasse stehen müssen.
    Leider muss ich vor jeder Abfrage an eine externe Datenbank die Verbindung neu aufbauen (und danach wieder zurück), da Contao keine zwei Verbindungen gleichzeitig verwalten kann.


    Hätte ich mit dem Auslagern in eine Klasse einiges an Performanceverlust?
    Eine Alternative wäre, die Abfragen in Funktionen auszulagern, denen dann jeweils die Verbindung als Parameter übergeben wird. Aber das finde ich noch unschöner.

    Mfg
    sans

  • #2
    1. Ist die Frage drüben gerade mal 1 1/2 Tage alt.
    allerdings kann mir dort niemand so recht helfen
    finde ich da etwas unpassend. Anmerkungen zu Crosspostings
    2. Findest Du wohl eher nen Entwickler für Contao in Contaoforum, als im Entwicklerforum jemanden, der zufällig mit Contao arbeitet
    3. Ist die Frage sehr allgemein gehalten. Da ich Contaos Struktur nicht kenne, weiß ich nicht was man da groß antworten sollte (und kennte*) ich sie, würde sich daran vermutlich wenig ändern), außer: na mach doch.

    *) igitt
    [COLOR="#F5F5FF"]--[/COLOR]
    [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
    [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
    [COLOR="#F5F5FF"]
    --[/COLOR]

    Kommentar


    • #3
      Irgendwie habe ich aber damit das Gefühl, dass es bis auf die Umsetzung nicht mehr viel mit OOP zu tun hat.
      Wieso nicht? Das klingt schon okay. Zu viel Grübelei über „das perfekte Design“ (tm) dauert meiner Meinung nach (a) lange und führt (b) trotzdem gerne zu verkomplizierendem Overengineering. Ist jetzt natürlich pauschal ausgedrückt, aber in einem Bruchteil der Zeit hast du's im Zweifel dreimal refaktoriert.

      (Damit will ich nicht sagen, dass Designüberlegungen schlecht wären. Meiner Erfahrung nach verliert man sich dabei aber gerne in Details und bremst sich selbst aus. Hängt aber auch davon ab, ob du in der Gruppe arbeitest oder allein. – Na ja, egal, ich schweife ab.)

      Hätte ich mit dem Auslagern in eine Klasse einiges an Performanceverlust?
      Nein. Nicht spürbar.

      Namespaces für deine Klassennamen (MyExtension_DownloadModel) wären vielleicht noch gut, falls du nicht zufällig die syntaktischen Namespaces (namespace-PHP-Sprachkonstrukt) nutzt.

      Kommentar


      • #4
        Zu viel Grübelei über „das perfekte Design“ (tm) dauert meiner Meinung nach (a) lange und führt (b) trotzdem gerne zu verkomplizierendem Overengineering.
        Sehe ich auch so - Für ein Plugin sieht das in meinen Augen auch ok aus - Auch in Hinblick auf OOP.

        Kommentar


        • #5
          Naja, schau dir mal ein paar PHP-Frameworks an. Da hat jede Tabelle auch ihre eigene Klasse. Deine Idee ist schon gut und macht sicherlich Sinn.

          Allerdings jedes mal die Datenbank-Verbidung neu aufzubauen halte ich für etwas unglücklich gelöst. Warum lagerst du das nicht in eine eigene Klasse aus, die sich wirklich nur um die Kommunikation mit der Datenbank kümmert?

          Die Klasse (ich nenn sie mal "Datasource") holst du dann in deine Models rein (z.B. der Dependency Injection). Somit muss die Verbindung nur einmal aufgebaut werden. Und solltest du mal die Datenbank wechseln musst du nur diese Klasse anpassen.

          Gruß,
          Max

          Kommentar


          • #6
            Was mich stören würde ist die Verwendung des Begriffs Model. Wenn da nur Abfragen drin stehen würde ich es nicht unbedingt als Model bezeichnen. Aber prinzipiell passt das schon.

            Kommentar


            • #7
              Hey vielen Dank für eure Antworten
              Wie es aussieht werde ich also in der Richtung bleiben.

              Ihr habt recht, ein perfektes Design ist nicht nötig und wahrscheinlich auch nicht möglich.
              Echte Namespaces sind eine gute Idee, da sowieso PHP > 5.3 auf dem Server läuft. "Namespaces" über Datei- bzw. Klassennamen möchte ich vermeiden, da eh schon alle Dateien (Vorgabe von Contao) im gleichen Ordner liegen müssen.

              Leider muss ich die Datenbankverbindung jedes mal neu aufbauen, da Contao nur eine Verbindung gleichzeitig verwalten kann. Aber eigentlich könnte ich auch selbst eine Verbindung herstellen. Die Contao Methoden wie execute() etc. sind ja eigentlich nur Wrapper für die PHP Befehle.
              Die vielen Connects drücken wahrscheinlich viel eher auf die Performance wie alles was mit OOP machbar ist

              Ich habe mir andere Frameworks angesehen: CakePHP und CodeIgniter machen es ähnlich wie mein Vorschlag. Von Zend konnte ich nichts konkretes finden. Und Flow3 und Symfony2 verwenden ein ähnliches System mit dem ich mich nicht auskenne. Wie nennt man das wenn PHP-Code über Kommentare (Flow3) oder mit use (Symfony2) gesteuert wird?


              Würde es ausreichen, wenn ich einfach in meinem BaseModel die Datenbankverbindung herstelle?
              Die Datenbank muss nicht austauschbar sein. Und wenn, würde es ja nicht ausreichen einfach nur die "Datasource" zu ändern, wenn ich in den Models direkt Mysqli-Funktionen verwende. Oder sehe ich das falsch?
              Mein Ziel ist es einfach ein sauberes Modul zu haben, das ggf. auch nach mir weiterentwickelt werden kann, ohne aber das ganze zu komplex werden zu lassen. D.h. irgendwelche eigenen DI-Container zu programmieren, oder fertige zu verwenden wäre mehr als Overkill


              @mquadrat: welchen Begriff würdest du stattdessen vorschlagen?

              Kommentar


              • #8
                da Contao nur eine Verbindung gleichzeitig verwalten kann.
                Na und? Die kannst Du doch nutzen.
                [COLOR="#F5F5FF"]--[/COLOR]
                [COLOR="Gray"][SIZE="6"][FONT="Georgia"][B]^^ O.O[/B][/FONT] [/SIZE]
                „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                [URL="http://www.php.de/javascript-ajax-und-mehr/107400-draggable-sorttable-setattribute.html#post788799"][B]Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“[/B][/URL][/COLOR]
                [COLOR="#F5F5FF"]
                --[/COLOR]

                Kommentar


                • #9
                  Ja, aber ich muss nach der Abfrage bzw. spätestens vor der nächsten Abfrage für Contao (z.B. Navigation, User Auth etc.) wieder auf die Contao Datenbank zurückwechseln.
                  Contao verwendet eine andere Datenbank wie die die ich aus meiner Schnittstelle ansprechen muss.

                  Kommentar

                  Lädt...
                  X