Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Vorwort
1 Einleitung
2 Einführung in eZ Components
3 Die Applikationsbasis
4 Fehlerbehandlung und Debugging
5 Konfiguration
6 Datenbankanbindung
7 ORM mit PersistentObject
8 Template
9 Übersetzung
10 Benutzereingaben validieren
11 Authentifizierung
12 Bildverarbeitung
13 Archive und Dateien
14 Mail
15 Logging
16 Diagramme
17 Feeds und Caching
18 Setup
A Inhalt der Buch-CD
Stichwort
Download: - ZIP, ca. 2,7 MB
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> /eZ Components | vor >>
eZ Components von Tobias Schlitt, Kore Nordmann Das Entwickler-Handbuch
eZ Components geb., mit CD 454 S., 39,90 Euro Galileo Computing ISBN 978-3-8362-1073-7 |
| 6 Datenbankanbindung
|  | 6.1 Abstraktion
|  |  | 6.1.1 Abstraktion der API
|  |  | 6.1.2 SQL-Abstraktion
|  |  | 6.1.3 Unterstützte RDBMS
|  | 6.2 Nutzung in der Applikation
|  | 6.3 Die Database-Komponente
|  |  | 6.3.1 PDO
|  |  | 6.3.2 Fluent-Interfaces
|  | 6.4 Integration von Database
|  |  | 6.4.1 Ein neues Blog Posting erstellen
|  |  | 6.4.2 Prepared-Statements
|  |  | 6.4.3 Update
|  |  | 6.4.4 Daten auslesen
|  | 6.5 Komplexere Abfragen
|  |  | 6.5.1 Manuelle Queries
|  |  | 6.5.2 Sub-Selects
|  |  | 6.5.3 Joins
|  |  | 6.5.4 LIMIT und ORDER BY
|  | 6.6 Erweiterte Möglichkeiten
|  |  | 6.6.1 Lazy-Initialization
|  |  | 6.6.2 Ein anderes RDBMS verwenden
|  | 6.7 Fazit
## 6.5 Komplexere Abfragen In den bisherigen Beispielen sind lediglich sehr simple Einschränkungen in den gezeigten Abfragen vorgekommen, namentlich die Überprüfung auf die Gleichheit eines Werts einer einzelnen Spalte. Die ezcDbExpressions-Klasse ermöglicht daneben noch komplexere Einschränkungen wie multiple Verknüpfungen durch aussagenlogisches AND und OR. Auch andere SQL-spezifische Vergleichsoperatoren wie IN() sind möglich. Eine vollständige Liste findet sich in der API-Dokumentation zur Database-Komponente. [http://ezcomponents.org/docs/api/latest/Database/ezcQueryExpression.html ] Komplexere Einschränkungen lassen den Aufbau der Abfragen über die Fluent-Interfaces immer mehr den weiter oben beschriebenen Fluent-Interfaces zum Rechnen mit komplexen Zahlen ähneln. Beispielhaft sei die Abfrage auf Kommentare zu einem bestimmten Blog-Eintrag von zwei Autoren nach einem bestimmten Zeitpunkt beschränkt. In reinem SQL sähe die Einschränkung in etwa folgendermaßen aus:
    WHERE
        entry_id = 1
        AND (
            name = 'kore'
            OR name = 'toby'
        )
        AND date > 123456789
Listing 6.10 Einschränkung über WHERE Mittels ezcDbExpression gestaltet sich der Code, um diese Einschränkung zu erzeugen, äußerst ähnlich:
    $e = $query->expr;
    $query->where(
        $e->eq(
            $db->quoteIdentifier( 'entry_id' ),
            $query->bindValue( 1 ) ),
        $e->lOr(
            $e->eq(
                $db->quoteIdentifier( 'name' ),
                $query->bindValue( 'kore' ) ),
            $e->eq(
                $db->quoteIdentifier( 'name' ),
                $query->bindValue( 'toby' ) )
        ),
        $e->gt(
            $db->quoteIdentifier( 'date' ),
            $query->bindValue( 123456789 ) )
    );
Listing 6.11 Eingeschränkte Query mit dem Query-Builder
    +------+--------------+----------------------------------------+
    | name | email        | body                                   |
    +------+--------------+----------------------------------------+
    | kore | kore@php.net | Schoen, dass Blog nun gestartet ist.   |
    +------+--------------+----------------------------------------+
    | toby | toby@php.net | Freut mich auch.                       |
    +------+--------------+----------------------------------------+
Listing 6.12 Ergebnis der eingeschränkten Query Wie das Beispiel deutlich macht, werden mehrere Parameter bei dem Aufruf von where() automatisch im SQL-Statement mit dem logischen Operator AND verknüpft. Die Vergleiche auf Gleichheit sind äquivalent zum obigen Beispiel, nur der vierte Vergleich unterscheidet sich durch die Verwendung von gt() (englisch: greater then, größer als). Die Namen der beiden Kommentarautoren sind durch ein logisches Oder verknüpft, da aber die Namen OR und AND in PHP reservierte Begriffe sind und damit nicht für Methoden- oder Funktionsnamen verwendet werden können, heißen die entsprechenden Methoden lOr() und lAnd(), wobei das »l« für logical steht, die logische, nicht bitweise Verknüpfung charakterisierend. ### 6.5.1 Manuelle Queries Das letzte Listing hat gezeigt, wie die Unabhängigkeit von den Eigenheiten der RDBMS auf Kosten der Komplexität des Programmcodes geht. Falls diese Abstraktion nicht benötigt wird oder plattformspezifische Optimierungen notwendig werden, können Sie über die Database-Komponente natürlich auch manuell aufgebaute Abfragen absetzen, die dennoch die Vorteile von Prepared-Statements nutzen können.
    $db = ezcDbInstance::get();
    $statement = $db->prepare( '
        SELECT name, email, body
        FROM comment
        WHERE
            entry_id = :id
            AND (
                name = :person_0 OR name = :person_1
            )
            AND date > :date' );
    $statement->execute( array(
        ':id' => 1,
        ':person_0' => 'kore',
        ':person_1' => 'toby',
        ':date' => 123456789,
    ) );
Listing 6.13 Manuelle Queries ausführen Der Methode prepare() wird in diesem Fall direkt die Abfrage in reinem SQL als String übergeben, der Platzhalter für die nachher einzufügenden Werte enthält. Diese Werte können der Abfrage nun, wie schon vorher durch den Aufruf von bindValue() auf $statement, assoziiert oder aber auch direkt im Aufruf von execute() als Array übergeben werden. Das Ergebnis dieser Abfrage gleich exakt der obigen Abfrage über den Query-Builder. PDO ermöglicht zwei Varianten der Referenzierung von Daten in Prepared-Statements: Über benannte Schlüssel wie im letzten Beispiel oder mittels ? in der Query. Die zugewiesenen Werte werden den Platzhaltern dann in der Reihenfolge ihres Vorkommens zugewiesen. Zu beachten ist bei diesem Beispiel natürlich, dass es nicht mehr unabhängig vom RDBMS funktioniert. In einigen Datenbanksystemen kann es nötig sein, Spaltennamen wie date zu maskieren, wobei sich die Art der Maskierung stark zwischen den verschiedenen Systemen unterscheidet. ### 6.5.2 Sub-Selects Zu den komplexeren SQL-Features, die der Query-Builder unterstützt, gehören Sub-Selects, die seit Version 4.1 auch von MySQL unterstützt werden und dadurch mit jedem der getesteten RDBMS funktionieren.
    $db = ezcDbInstance::get();
    $query = $db->createSelectQuery();
    $subquery = $query->Sub-Select();
    $subquery
        ->selectDistinct( $db->quoteIdentifier( 'entry_id' ) )
        ->from( $db->quoteIdentifier( 'entry_tag' ) );

    $query
        ->select( $db->quoteIdentifier( 'title' ) )
        ->from( $db->quoteIdentifier( 'entry' ) )
        ->where(
            $query->expr->in(
                $db->quoteIdentifier( 'id' ),
                (string) $subquery )
        );

    $statement = $query->prepare();
    $statement->execute();
Listing 6.14 Subselect mit dem Query-Builder
    +---------------------+
    | title               |
    +---------------------+
    | Erster Blogeintrag  |
    +---------------------+
    | Kapitel 6: Database |
    +---------------------+
Listing 6.15 Ergebnis des Subselects mit dem Query-Builder Diese Abfrage listet die Titel aller Blog-Einträge auf, die mindestens einen Tag assoziiert haben. Dazu wird wie gewohnt aus dem DB-Handler eine SELECT-Query erzeugt, auf deren Basis ein Subquery-Objekt erzeugt wird. Seit der Version 1.3 (die diesem Buch zugrunde liegt) kann die Database-Komponente mit DISTINCT-Queries umgehen, sodass die aufgebaute Subquery eine Liste von einmaligen IDs aller Blog-Eintrage zurückgibt, die eine Tag-Assoziation besitzen. Die SELECT-Query verwendet die entsprechende Subquery mit IN(), um damit die Liste der Blog-Einträge, deren Titel angezeigt werden soll, zu begrenzen. ### 6.5.3 Joins Eine anderes, in komplexeren Abfragen häufig verwendetes SQL-Konstrukt, sind Joins, die ebenfalls von allen verwendeten RDBMS in deren aktuellen Versionen unterstützt werden.
    $db = ezcDbInstance::get();
    $query = $db->createSelectQuery();
    $query
        ->select(
            $db->quoteIdentifier( 'title' ),
            $db->quoteIdentifier( 'tag' )
        )
        ->from( $db->quoteIdentifier( 'entry' ) )
        ->rightJoin(
            $db->quoteIdentifier( 'entry_tag' ),
            $query->expr->eq(
                $db->quoteIdentifier( 'entry_tag' ) . '.' .
                    $db->quoteIdentifier( 'entry_id' ),
                $db->quoteIdentifier( 'entry' ) . '.' .

                    $db->quoteIdentifier( 'id' )
            )
        )
        ->leftJoin(
            $db->quoteIdentifier( 'tag' ),
            $query->expr->eq(
                $db->quoteIdentifier( 'tag' ) . '.' .
                    $db->quoteIdentifier( 'id' ),
                $db->quoteIdentifier( 'entry_tag' ) . '.' .
                    $db->quoteIdentifier( 'tag_id' ) )
        );
    $statement = $query->prepare();
    $statement->execute();
Listing 6.16 Joins mit dem Query-Builder Diese Abfrage listet alle Blog-Eintrage inklusive ihrer assoziierten Tags auf. Wie das Listing zeigt, werden die verschiedenen JOIN-Typen vom Query-Builder unterstützt, und der RIGHT JOIN stellt an dieser Stelle sicher, dass nur Blog-Einträge mit Tags in der Liste auftauchen. Die Methoden, um Joins in die Abfrage einzubauen, erwarten als ersten Parameter die Tabelle, mit denen das Daten-Produkt gebildet werden soll und als zweiten Parameter die Bedingung, unter der der Join durchgeführt werden soll.
    +---------------------+----------+
    | title               | tag      |
    +---------------------+----------+
    | Erster Blogeintrag  | galileo  |
    +---------------------+----------+
    | Erster Blogeintrag  | ezc      |
    +---------------------+----------+
    | Erster Blogeintrag  | blog     |
    +---------------------+----------+
    | Kapitel 6: Database | ezc      |
    +---------------------+----------+
    | Kapitel 6: Database | database |
    +---------------------+----------+
    | Kapitel 6: Database | blog     |
    +---------------------+----------+
Listing 6.17 Resultat Queries ### 6.5.4 LIMIT und ORDER BY Das LIMIT-Statement zur Begrenzung (Limitierung) der Anzahl der zurückgegebenen Datensätze wurde ursprünglich gerade für das Durchblättern vieler Datensätze in Webapplikationen bereitgestellt. Die einzelnen Treiber stellen jeweils eine spezifische Implementierung für dieses Konstrukt bereit. Natürlich steht es damit auch im Query-Builder zur Verfügung und wird zum Beispiel für das Oracle-Datenbanksystem entsprechend emuliert.
    $query
        ->select( $db->quoteIdentifier( 'tag' ) )
        ->from( $db->quoteIdentifier( 'tag' ) )
        ->limit( 2, 1 )
        ->orderBy( $db->quoteIdentifier( 'tag' ) );
Listing 6.18 Limit und Order-By im Query-Builder
    +----------+
    | tag      |
    +----------+
    | database |
    +----------+
    | ezc      |
    +----------+
Listing 6.19 Ergebnis Limit und Order-By im Query-Builder Die Beispielabfrage gibt einen Teil der sortierten Liste der in der Datenbank enthaltenen Tags aus. Mit limit() wird als erster Parameter die maximale Anzahl der Datensätze spezifiziert, während der zweite Parameter den Offset für das SELECT angibt, also die Nummer des Datensatzes, mit dem zu beginnen ist. Die oderBy()-Methode akzeptiert wie gewohnt mindestens eine Spalte, nach der die Ausgabe sortiert wird, kann aber auch mit mehreren Spalten umgehen oder mehrfach aufgerufen werden. ### Ihr Kommentar Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück | <top> | vor >>
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Buchempfehlungen
| PHP 5.3 und MySQL 5.1
| Besser PHP programmieren
| Webshops mit Magento
| Sichere Webanwendungen
| PHP 5.3 und MySQL 5.1 - Videotraining
| Apache 2
| Suchmaschinen- Optimierung für Webentwickler
| Joomla! 1.5
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de