1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 21597 -->
4 <sect1 id="zend.db.table">
5 <title>Zend_Db_Table</title>
7 <sect2 id="zend.db.table.introduction">
8 <title>Einführung</title>
11 Die <classname>Zend_Db_Table</classname> Klasse ist eine Objekt-Orientierte
12 Schnittstelle zu Datenbank Tabellen. Sie bietet Methoden für viele gängige Operationen
13 an Tabellen. Die Basisklasse ist erweiterbar, daher kann eigene Logik eingeführt werden.
17 Die <classname>Zend_Db_Table</classname> Lösung ist eine Implementation des
18 <ulink url="http://www.martinfowler.com/eaaCatalog/tableDataGateway.html">Table Data
19 Gateway</ulink> Patterns. Die Lösung schließt außerdem eine Klasse ein, welche das
20 <ulink url="http://www.martinfowler.com/eaaCatalog/rowDataGateway.html">Row Data
21 Gateway</ulink> Pattern implementiert.
25 <sect2 id="zend.db.table.concrete">
26 <title>Zend_Db_Table als konkrete Klasse verwenden</title>
29 Ab Zend Framework 1.9 kann man <classname>Zend_Db_Table</classname> instanziieren. Der
30 zusätzliche Vorteil ist das man die Basisklasse nicht erweitern und konfigurieren muß um
31 einfache Operationen wie auswählen, einfügen, aktualisieren und löschen in einer
32 einzelnen Tabelle durchzuführen. Anbei ist ein Beispiel der einfachsten Verwendung.
35 <example id="zend.db.table.defining.concrete-instantiation.example1">
36 <title>Eine Table Klasse nur mit dem Stringnamen deklarieren</title>
38 <programlisting language="php"><![CDATA[
39 Zend_Db_Table::setDefaultAdapter($dbAdapter);
40 $bugTable = new Zend_Db_Table('bug');
45 Das obige Beispiel zeigt das einfachste Beispiel. Nicht alle der unten beschriebenen
46 Optionen sollten für die Konfiguration von <classname>Zend_Db_Table</classname> Tabellen
47 durchgeführt werden. Wenn man in der Lage sein will das konkrete Verwendungsbeispiel
48 zusätzlich zu den komplexeren Abhängigkeits Features zu verwenden sehen Sie in die
49 <classname>Zend_Db_Table_Definition</classname> Dokumentation.
53 <sect2 id="zend.db.table.defining">
54 <title>Definieren einer Table Klasse</title>
57 Für jede Tabelle der Datenbank auf die zugegriffen werden soll, sollte eine eine Klasse
58 erzeugt werden, welche <classname>Zend_Db_Table_Abstract</classname> erweitert.
61 <sect3 id="zend.db.table.defining.table-schema">
62 <title>Definieren des Tabellennamens und Schemas</title>
65 Die Tabelle der Datenbank, für welche die Klasse bestimmt ist, wird mit der
66 protected Variablen <varname>$_name</varname> angegeben. Es ist ein String, welcher
67 den Namen der Tabelle enthalten muss, wie er in der Datenbank erscheint.
70 <example id="zend.db.table.defining.table-schema.example1">
71 <title>Angeben einer Table Klasse mit ausdrücklichem Tabellennamen</title>
73 <programlisting language="php"><![CDATA[
74 class Bugs extends Zend_Db_Table_Abstract
76 protected $_name = 'bugs';
82 Wird keine Tabellenname angegeben, so wird ein Standard verwendet, welcher dem
83 Namen der Klasse entspricht. Wird sich auf diesen Standard verlassen, so muss der
84 Klassenname der Schreibweise der Tabelle entsprechen, wie sie in der Datenbank
88 <example id="zend.db.table.defining.table-schema.example">
89 <title>Angeben einer Table Klasse mit inbegriffenem Tabellennamen</title>
91 <programlisting language="php"><![CDATA[
92 class bugs extends Zend_Db_Table_Abstract
94 // Tabellenname entspricht dem Klassennamen
100 Es kann auch ein Schema für die Tabelle angegeben werden. Entweder mit der protected
101 Variablen <varname>$_schema</varname> oder mit dem Schema vorangestellt in der
102 <varname>$_name</varname> Eigenschaft. Jedes Schema welches in der
103 <varname>$_name</varname> Eigenschaft angegeben ist wird vorrangig gegenüber dem
104 Schema der <varname>$_schema</varname> Eigenschaft behandelt. In einigen
105 <acronym>RDBMS</acronym> Marken ist die Bezeichnung für Schema "database" oder
106 "tablespace", wird aber ähnlich verwendet.
109 <example id="zend.db.table.defining.table-schema.example3">
110 <title>Angeben einer Table Klasse mit Schema</title>
112 <programlisting language="php"><![CDATA[
113 // Erste Möglichkeit:
114 class Bugs extends Zend_Db_Table_Abstract
116 protected $_schema = 'bug_db';
117 protected $_name = 'bugs';
120 // Zweite Möglichkeit:
121 class Bugs extends Zend_Db_Table_Abstract
123 protected $_name = 'bug_db.bugs';
126 // Wenn Schema sowohl in $_name als auch $_schema angegeben wird, so bekommt $_name vorrang:
128 class Bugs extends Zend_Db_Table_Abstract
130 protected $_name = 'bug_db.bugs';
131 protected $_schema = 'ignored';
137 Die Schema und Tabellennamen können auch mit Konstruktor Konfigurationsdirektiven
138 angegeben werden, welche jegliche Standardwerte, angegeben in den
139 <varname>$_name</varname> und <varname>$_schema</varname> Eigenschaften,
140 überschreiben. Eine Schema Angabe welche mit der <property>name</property> Directive
141 angegeben wurde überschreibt jeglichen Wert welcher von der
142 <property>schema</property> Option bereitgestellt ist.
145 <example id="zend.db.table.defining.table-schema.example.constructor">
146 <title>Angebend von Tabellen und Schemanamen während der Instanziierung</title>
148 <programlisting language="php"><![CDATA[
149 class Bugs extends Zend_Db_Table_Abstract
153 // Erste Möglichkeit:
155 $tableBugs = new Bugs(array('name' => 'bugs', 'schema' => 'bug_db'));
157 // Zweite Möglichkeit:
159 $tableBugs = new Bugs(array('name' => 'bug_db.bugs'));
161 // Wenn Schema sowohl in $_name als auch $_schema angegeben wird,
162 // so bekommt $_name vorrang:
164 $tableBugs = new Bugs(array('name' => 'bug_db.bugs',
165 'schema' => 'ignored'));
170 Wenn kein Schemaname angegeben wird, so wird als Standard der Schemaname des
171 Datenbankadapters verwendet.
175 <sect3 id="zend.db.table.defining.primary-key">
176 <title>Angeben des Primärschlüssels der Tabelle</title>
179 Jede Tabelle muss einen Primärschlüssel haben. Die Spalte des Primärschlüssels kann
180 mit der protected Variablen <varname>$_primary</varname> angegeben werden. Sie
181 enthält entweder einen String, welcher die einzelen Spalte benennt, oder ein Array
182 von Spaltennamen, wenn der Primärschlüssel ein zusammengesetzter Schlüssel ist.
185 <example id="zend.db.table.defining.primary-key.example">
186 <title>Beispiel für das spezifizieren eines Primärschlüssels</title>
188 <programlisting language="php"><![CDATA[
189 class Bugs extends Zend_Db_Table_Abstract
191 protected $_name = 'bugs';
192 protected $_primary = 'bug_id';
198 Wenn kein Primärschlüssel angegeben wird, versucht
199 <classname>Zend_Db_Table_Abstract</classname> den Primärschlüssel mit Hilfe der
200 <methodname>describeTable()</methodname> Methode zu ermitteln.
205 Jede Table Klasse muss wissen mit welche(r/n) Spalte(n) Zeilen eindeutig
206 identifiziert werden können. Wenn keine Primärschlüssel Spalte(n) in der
207 Klassendefinition oder als Argument für den Konstruktor angegeben wurde und
208 nicht aus den Metadaten der Tabelle mit Hilfe der
209 <methodname>describeTable()</methodname> Methode ermittelt werden kann, dann
210 kann die Tabelle nicht mit <classname>Zend_Db_Table</classname> verwendet
216 <sect3 id="zend.db.table.defining.setup">
217 <title>Überschreiben von Table Setup Methoden</title>
220 Wenn eine Instanz einer Table Klasse erzeugt wird, ruft der Konstruktor einige
221 protected Methoden auf, die Metadaten der Tabelle initialisieren. Jede dieser
222 Methoden kann erweitert werden um Metadaten explizit anzugeben. Dabei darf nicht
223 vergessen werden am Ende der eigenen Methode die gleichnamige Methode der
224 Parentklasse aufzurufen.
227 <example id="zend.db.table.defining.setup.example">
228 <title>Beispiel für das Überschreiben der _setupTableName() Methode</title>
230 <programlisting language="php"><![CDATA[
231 class Bugs extends Zend_Db_Table_Abstract
233 protected function _setupTableName()
235 $this->_name = 'bugs';
236 parent::_setupTableName();
243 Folgende Setup Methoden sind überschreibbar:
249 <methodname>_setupDatabaseAdapter()</methodname> überprüft ob ein Adapter
250 bereitgestellt wird; nimmt einen Standardadapter aus der Registry, wenn
251 benötigt. Durch das Überschreiben dieser Methode kann ein Datenbankadapter
252 aus einer anderen Quelle gesetzt werden.
258 <methodname>_setupTableName()</methodname> setzt den standard Tabellennamen
259 auf den Namen der Klasse. Durch das Überschreiben dieser Methode kann der
260 Tabellenname gesetzt werden bevor dieses Standardverhalten abläuft.
266 <methodname>_setupMetadata()</methodname> setzt das Schema wenn der
267 Tabellenname dem Muster "<command>schema.table</command>" entspricht; ruft
268 <methodname>describeTable()</methodname> auf um Metadaten Informationen zu
269 erhalten; Standardisiert das <varname>$_cols</varname> Array auf die
270 Spalten wie von <methodname>describeTable()</methodname> geliefert. Durch
271 das Überschreiben dieser Methode können die Spalten angegeben werden.
277 <methodname>_setupPrimaryKey()</methodname> standardisiert die
278 Primärschlüssel Spalten zu denen geliefert von
279 <methodname>describeTable()</methodname>; prüft ob die Primärschlüssel
280 Spalten im <varname>$_cols</varname> Array enthalten sind. Durch
281 das Überschreiben dieser Methode können die Primärschlüssel Spalten
288 <sect3 id="zend.db.table.initialization">
289 <title>Tabellen Initialisierung</title>
292 Wenn Anwendungs-spezifische Logik initialisiert werden soll wenn eine
293 Tabellenklasse erstellt wird, kann man entscheiden die Aufgaben in die
294 <methodname>init()</methodname> Methode zu verschieben, die aufgerufen wird nachdem
295 alle Tabellen Metadaten bearbeitet wurden. Das ist besser als die
296 <methodname>__construct()</methodname> Methode wenn die Metadaten nicht
297 programmtechnisch verändert werden sollen.
300 <example id="zend.db.table.defining.init.usage.example">
301 <title>Beispielverwendung der init() Methode</title>
303 <programlisting language="php"><![CDATA[
304 class Bugs extends Zend_Db_Table_Abstract
306 protected $_observer;
308 public function init()
310 $this->_observer = new MyObserverClass();
318 <sect2 id="zend.db.table.constructing">
319 <title>Erzeugen einer Instanz einer Tabelle</title>
322 Bevor eine Table Klasse verwendet werden kann muss eine Instanz mit dem Konstruktor
323 erzeugt werden. Das Konstruktor Argument ist ein Array von Optionen. Die wichtigste
324 Option für einen Tabellenkonstruktor ist die Instanz der Adapterklasse, welche eine live
325 Verbindung zu einem <acronym>RDBMS</acronym> repräsentiert. Es gibt drei Möglichkeiten
326 den Datenbankadapter einer Tabellenklasse anzugeben und diese sind unten beschrieben:
329 <sect3 id="zend.db.table.constructing.adapter">
330 <title>Angeben eines Datenbankadapters</title>
333 Der erste Weg einen Datenbankadapter an eine Table Klasse bereitzustellen ist, ein
334 Objekt des Typs <classname>Zend_Db_Adapter_Abstract</classname> im Options Array,
335 bezeichnet mit dem Schlüssel '<property>db</property>', zu übergeben.
338 <example id="zend.db.table.constructing.adapter.example">
340 Beispiel für das Erzeugen einer Tabelle mit Nutzung eines Adapterobjekts
343 <programlisting language="php"><![CDATA[
344 $db = Zend_Db::factory('PDO_MYSQL', $options);
346 $table = new Bugs(array('db' => $db));
351 <sect3 id="zend.db.table.constructing.default-adapter">
352 <title>Setzen eines Standard-Datenbankadapters</title>
355 Der zweite Weg einer Table Klasse einen Datenbankadapter bereit zu stellen ist es,
356 ein Objekt des Typs <classname>Zend_Db_Adapter_Abstract</classname> zu deklarieren
357 und als Standard für alle nachfolgenden Instanzen von Table der Applikation zu
358 setzen. Dies kann mit der static Methode
359 <methodname>Zend_Db_Table_Abstract::setDefaultAdapter()</methodname> getan werden.
360 Das Argument ist ein Objekt des Typs
361 <classname>Zend_Db_Adapter_Abstract</classname>.
364 <example id="zend.db.table.constructing.default-adapter.example">
365 <title>Beispiel für das erstellen von Table mit einem Standardadapter</title>
367 <programlisting language="php"><![CDATA[
368 $db = Zend_Db::factory('PDO_MYSQL', $options);
369 Zend_Db_Table_Abstract::setDefaultAdapter($db);
378 Es kann geeignet sein den Datenbankadapter an einer zentralen Stelle der Anwendung,
379 wie dem Bootstrap, zu erzeugen, und als Standardadapter zu speichern. Dies hilft
380 sicher zu stellen, das der verwendete Adapter in der gesamten Anwendung der gleiche
381 ist. Allerdings kann nur eine einzelne Adapterinstanz als Standardadapter verwendet
386 <sect3 id="zend.db.table.constructing.registry">
387 <title>Speichern eines Datenbankadapters in der Registry</title>
390 Der dritte Weg einer Table Klasse einen Datenbankadapter bereit zu stellen ist es
391 einen String in dem Optionsarray zu übergeben, auch mit dem
392 '<property>db</property>' Schlüssel identifiziert. Der String wird als Schlüssel der
393 statischen <classname>Zend_Registry</classname> Instanz verwendet, wo der Eintrag
394 mit dem Schlüssel ein Objekt des Typs
395 <classname>Zend_Db_Adapter_Abstract</classname> ist.
398 <example id="zend.db.table.constructing.registry.example">
399 <title>Beispiel für das Erzeugen von Table mit einem Registry Schlüssel</title>
401 <programlisting language="php"><![CDATA[
402 $db = Zend_Db::factory('PDO_MYSQL', $options);
403 Zend_Registry::set('my_db', $db);
407 $table = new Bugs(array('db' => 'my_db'));
412 Wie das Setzen eines Standardadapters, bietet auch dieses sicher zu stellen das die
413 gleiche Adapter Instanz in der gesamten Anwendung verwendet wird. Nutzen der
414 Registry ist flexibler, da mehr als eine Adapterinstanz gepeichert werden kann. Eine
415 angegebene Adapterinstanz ist spezifisch für eine bestimmte <acronym>RDBMS</acronym>
416 Marke und Datenbankinstanz. Wenn die Anwendung Zugriff auf mehrere Datenbanken
417 benötigt oder auch mehrere Datenbank Marken, dann müssen mehrere Adapter verwendet
423 <sect2 id="zend.db.table.insert">
424 <title>Zeilen in eine Tabelle einfügen</title>
427 Table Objekte können verwendet werden um Zeilen in die Datenbank Tabelle einzufügen auf
428 der das Table Objekt basiert. Hierzu kann die <methodname>insert()</methodname> Methode
429 des Table Objektes verwendet werden. Das Argument ist ein assoziatives Array, das
430 Spalten Namen mit Werten verbindet.
433 <example id="zend.db.table.insert.example">
434 <title>Beispiel für das Einfügen in eine Tabelle</title>
436 <programlisting language="php"><![CDATA[
440 'created_on' => '2007-03-22',
441 'bug_description' => 'Irgendwas falsch',
442 'bug_status' => 'NEW'
445 $table->insert($data);
450 Standardmäßig werden Werte im Daten Array als literale Werte eingefügt durch das
451 Verwenden von Parametern. Wenn es notwendig ist das diese als <acronym>SQL</acronym>
452 Ausdruck behandelt werden, muß sichergestellt werden das Sie sich von reinen Strings
453 unterscheiden. Es kann ein Objekt vom Typ <classname>Zend_Db_Expr</classname> verwendet
454 werden um das zu bewerkstelligen.
457 <example id="zend.db.table.insert.example-expr">
458 <title>Beispiel für das Einfügen von Ausdrücken in einer Tabelle</title>
460 <programlisting language="php"><![CDATA[
464 'created_on' => new Zend_Db_Expr('CURDATE()'),
465 'bug_description' => 'Irgendwas ist falsch',
466 'bug_status' => 'NEU'
472 Um obigen Beispiel vom Einfügen von Zeilen, wird angenommen das die Tabelle einen
473 automatischen Primärschlüssel hat. Das ist das Standardverhalten von
474 <classname>Zend_Db_Table_Abstract</classname>, aber es gibt auch andere Typen von
475 Primärschlüssel. Das folgende Kapitel beschreibt wie verschiedene Typen von
476 Primärschlüssel unterstützt werden.
479 <sect3 id="zend.db.table.insert.key-auto">
480 <title>Eine Tabelle mit einem automatischen Primärschlüssel verwenden</title>
483 Ein automatischer Primärschlüssel erzeigt einen eindeutigen Integerwert wenn die
484 Spalte des Primären Typs in der eigenen <acronym>SQL</acronym>
485 <constant>INSERT</constant> Anweisung unterdrückt wird.
489 Wenn die geschützte Variable <varname>$_sequence</varname>, in
490 <classname>Zend_Db_Table_Abstract</classname>, als boolscher Wert
491 <constant>TRUE</constant> definiert wird, nimmt die Klasse an das die Tabelle einen
492 automatischen Primärschlüssel hat.
495 <example id="zend.db.table.insert.key-auto.example">
497 Beispiel für das Deklarierens einer Tabelle mit einem automatischen
501 <programlisting language="php"><![CDATA[
502 class Bugs extends Zend_Db_Table_Abstract
504 protected $_name = 'bugs';
506 // Das ist der Standardwert in der Zend_Db_Table_Abstract Klasse;
507 // er muß nicht definiert werden.
508 protected $_sequence = true;
514 MySQL, Microsoft <acronym>SQL</acronym> Server, und SQLite sind Beispiele von
515 <acronym>RDBMS</acronym> Marken die automatische Primärschlüssel unterstützen.
519 PostgreSQL hat eine <constant>SERIAL</constant> Notation die implizit eine Sequenz
520 definiert die auf den Tabellen- und Spaltennamen basiert, und diese Sequenz
521 verwendet, um einen Schlüsselwert für neue Zeilen zu erstellen.
522 <acronym>IBM</acronym> <acronym>DB2</acronym> hat eine
523 <constant>IDENTITY</constant> Notation die ähnlich arbeitet. Wenn eine dieser
524 Notationen verwendet wird, muß der <classname>Zend_Db_Table</classname> Klasse
525 mitgeteilt werden das Sie eine automatische Spalte hat, indem
526 <varname>$_sequence</varname> auf <constant>TRUE</constant> gesetzt wird.
530 <sect3 id="zend.db.table.insert.key-sequence">
531 <title>Eine Tabelle mit einer Sequenz verwenden</title>
534 Eine Sequenz ist ein Datenbank Objekt das einen eindeutigen Wert erstellt, der als
535 Wert des Primärschlüssels in einer oder mehreren Tabellen der Datenbank verwendet
540 Wenn <varname>$_sequence</varname> als String definiert wird, nimmt
541 <classname>Zend_Db_Table_Abstract</classname> an das der String den Namen des
542 Sequenz Objektes in der Datenbank benennt. Die Sequenz wird aufgerufen um einen
543 neuen Wert zu erstellen, und dieser Wert wird in der <constant>INSERT</constant>
547 <example id="zend.db.table.insert.key-sequence.example">
548 <title>Beispiel für das Deklaration einer Tabelle mit einer Sequenz</title>
550 <programlisting language="php"><![CDATA[
551 class Bugs extends Zend_Db_Table_Abstract
553 protected $_name = 'bugs';
555 protected $_sequence = 'bug_sequence';
561 Oracle, PostgreSQL, und <acronym>IBM</acronym> <acronym>DB2</acronym> sind Beispiele
562 von <acronym>RDBMS</acronym> Marken die Sequenz Objekte in der Datenbank
567 PostgreSQL und <acronym>IBM</acronym> <acronym>DB2</acronym> haben auch einen Syntax
568 der Sequenzen implizit definiert und diese mit Spalten assoziiert. Wenn diese
569 Notation verwendet wird, muß der Tabelle gesagt werden das Sie eine automatische
570 Schlüsselspalte besitzt. Der Name der Sequenz muß nur in den Fällen als String
571 definiert werden in denen die Sequenz explizit aufgerufen wird um den nächsten
572 Schlüsselwert zu erhalten.
576 <sect3 id="zend.db.table.insert.key-natural">
577 <title>Eine Tabelle mit einem natürlichen Schlüssel verwenden</title>
580 Einige Tabellen haben natürliche Schlüssel. Das bedeutet das der Schlüssel nicht
581 automatisch durch die Tabelle oder eine Sequenz erstellt wird. Der Wert für den
582 Primärschlüssel muß in diesem Fall selbst definiert werden.
586 Wenn <varname>$_sequence</varname> als boolsches <constant>FALSE</constant>
587 definiert wird, nimmt <classname>Zend_Db_Table_Abstract</classname> an das die
588 Tabelle einen natürlichen Primärschlüssel hat. Es müssen Werte für die Spalte des
589 Primärschlüssels im Array der Daten definiert werden die an die
590 <methodname>insert()</methodname> Methode übergeben werden, andernfalls wird diese
591 Methode eine <classname>Zend_Db_Table_Exception</classname> werfen.
594 <example id="zend.db.table.insert.key-natural.example">
596 Beispiel für das Definieren einer Tabelle mit einem natürlichen Schlüssel
599 <programlisting language="php"><![CDATA[
600 class BugStatus extends Zend_Db_Table_Abstract
602 protected $_name = 'bug_status';
604 protected $_sequence = false;
611 Alle <acronym>RDBMS</acronym> Marken unterstützen Tabellen mit natürlichen
612 Schlüsseln. Beispiele von Tabellen die oft so definiert werden das Sie
613 natürliche Schlüssel besitzen sind Lookup Tabellen, Durchschnitts Tabellen in
614 viele-zu-viele Beziehungen, oder die meisten Tabellen mit komponierten
621 <sect2 id="zend.db.table.update">
622 <title>Zeilen in einer Tabelle aktualisieren</title>
625 Spalten können in der Datenbanktabelle aktualisiert werden indem die
626 <methodname>update()</methodname> Methode der Table Klasse verwendet wird. Diese Methode
627 nimmt zwei Argumente: ein assoziatives Array von Spalten die geändert werden sollen und
628 neue Werte die diesen Spalten hinzugefügt werden; und einen <acronym>SQL</acronym>
629 Ausdruck der in der <constant>WHERE</constant> Klausel verwendet wird, als Kriterium für
630 die Zeilen die in der <constant>UPDATE</constant> Operation geändert werden sollen.
633 <example id="zend.db.table.update.example">
634 <title>Beispiel für das Aktualisieren von Zeilen in einer Tabelle</title>
636 <programlisting language="php"><![CDATA[
640 'updated_on' => '2007-03-23',
641 'bug_status' => 'FIXED'
644 $where = $table->getAdapter()->quoteInto('bug_id = ?', 1234);
646 $table->update($data, $where);
651 Da die <methodname>update()</methodname> Methode der Tabelle zur
652 <link linkend="zend.db.adapter.write.update"><methodname>update()</methodname></link>
653 Methode des Datenbank Adapters weiterleitet, kann das zweite Argument ein Array von
654 <acronym>SQL</acronym> Ausdrücken sein. Diese Ausdrücke werden als Boolsche Terme
655 kombiniert indem ein <constant>AND</constant> Operator verwendet wird.
660 Die Werte und Identifizierer im <acronym>SQL</acronym> Ausdruck werden nicht in
661 Anführungszeichen gesetzt. Wenn Werte oder Identifizierer vorhanden sind die das
662 Setzen in Anführungszeichen benötigen, ist man selbst dafür zuständig das dies getan
663 wird. Die <methodname>quote()</methodname>, <methodname>quoteInto()</methodname> und
664 <methodname>quoteIdentifier()</methodname> Methoden des Datenbank Adapters können
665 dafür verwendet werden.
670 <sect2 id="zend.db.table.delete">
671 <title>Zeilen aus einer Tabelle löschen</title>
674 Zeilen können von einer Datenbanktabelle gelöscht werden indem die
675 <methodname>delete()</methodname> Methode verwendet wird. Diese Methode nimmt ein
676 Argument, welches ein <acronym>SQL</acronym> Ausdruck ist, der in der
677 <constant>WHERE</constant> Klausel als Kriterium dafür verwendet wird, welche Zeilen
678 gelöscht werden sollen.
681 <example id="zend.db.table.delete.example">
682 <title>Beispiel für das Löschen von Zeilen einer Tabelle</title>
684 <programlisting language="php"><![CDATA[
687 $where = $table->getAdapter()->quoteInto('bug_id = ?', 1235);
689 $table->delete($where);
694 Da die <methodname>delete()</methodname> Methode der Tabelle zur
695 <link linkend="zend.db.adapter.write.delete"><methodname>delete()</methodname></link>
696 Methode des Datenbank Adapters weiterleitet, kann das Argument ein Array von
697 <acronym>SQL</acronym> Ausdrücken sein. Diese Ausdrücke werden als boolsche Terme
698 kombiniert indem ein <constant>AND</constant> Operator verwendet wird.
703 Die Werte und Identifizierer im <acronym>SQL</acronym> Ausdruck werden nicht in
704 Anführungszeichen gesetzt. Wenn Werte oder Identifizierer vorhanden sind die das
705 Setzen in Anführungszeichen benötigen, ist man selbst dafür zuständig das dies getan
706 wird. Die <methodname>quote()</methodname>, <methodname>quoteInto()</methodname> und
707 <methodname>quoteIdentifier()</methodname> Methoden des Datenbank Adapters können
708 dafür verwendet werden.
713 <sect2 id="zend.db.table.find">
714 <title>Zeilen durch den Primärschlüssel finden</title>
717 Die Datenbanktabelle kann nach passenden Zeilen für spezifizierte Werte im
718 Primärschlüssel abgefragt werden, indem die <methodname>find()</methodname> Methode
719 verwendet wird. Das erste Argument dieser Methode ist entweder ein einzelner Wert oder
720 ein Array von Werten die dem Primärschlüssel dieser Tabelle entsprechen.
723 <example id="zend.db.table.find.example">
724 <title>Beispiel für das Finden von Zeilen durch Werte des Primärschlüssels</title>
726 <programlisting language="php"><![CDATA[
729 // Eine einzelne Zeile finden
730 // Gibt ein Rowset zurück
731 $rows = $table->find(1234);
733 // Mehrere Zeilen finden
734 // Gibt auch ein Rowset zurück
735 $rows = $table->find(array(1234, 5678));
740 Wenn ein einzelner Wert spezifiziert wird, gibt die Methode auch maximal eine Zeile
741 zurück, weil ein Primärschlüssel keinen doppelten Wert haben kann und es maximal eine
742 Zeile in der Datenbank gibt die dem spezifizierten Wert entspricht. Wenn mehrere Werte
743 in einem Array spezifiziert werden, gibt die Methode maximal soviele Zeilen zurück wie
744 die Anzahl an unterschiedlichen Werten die spezifiziert wurden.
748 Die <methodname>find()</methodname> Methode kann weniger Zeilen zurückgeben als die
749 Anzahl an Werten die für den Primärschlüssel definiert wurden, wenn einige der Werte
750 keiner Zeile in der Datenbank Tabelle entsprechen. Die Methode kann sogar null Zeilen
751 zurückgeben. Weil die Anzahl an zurückgegebenen Zeilen variabel ist, gibt die
752 <methodname>find()</methodname> Methode ein Objekt vom Typ
753 <classname>Zend_Db_Table_Rowset_Abstract</classname> zurück.
757 Wenn der Primärschlüssel ein komponierter Schlüssel ist, als einer der aus mehreren
758 Spalten besteht, können die zusätzlichen Spalten als zusätzliche Argumente in der
759 <methodname>find()</methodname> Methode definiert werden. Es müssen soviele Argumente
760 angegeben werden wie Spalten im Primärschlüssel der Tabelle existieren.
764 Um mehrere Zeilen von einer Tabelle mit einem kombinierten Primärschlüssel zu finden,
765 muß ein Array für jedes der Argumente übergeben werden. Alle dieser Arrays müssen die
766 gleiche Anzahl an Elementen haben. Die Werte in jedem Array werden in Tupeln geformt und
767 gereiht; zum Beispiel definiert das erste Element in allen Array Argumenten den ersten
768 kombinierten Wert des Primärschlüssels, das zweite Element von allen Arrays definiert
769 den zweiten kombinierten Wert des Primärschlüssels, und so weiter.
772 <example id="zend.db.table.find.example-compound">
774 Beispiel für das Finden von Zeilen durch Werte von kombinierten Primärschlüsseln
778 Der Aufruf von <methodname>find()</methodname> anbei um mehreren Zeilen zu
779 entsprechen kann zwei Zeilen in der Datenbank entsprechen. Die erste Zeile muß den
780 Wert des Primärenschlüssels (1234, 'ABC') haben, und die zweite Zeile den Wert des
781 Primärschlüssels (5678, 'DEF').
784 <programlisting language="php"><![CDATA[
785 class BugsProducts extends Zend_Db_Table_Abstract
787 protected $_name = 'bugs_products';
788 protected $_primary = array('bug_id', 'product_id');
791 $table = new BugsProducts();
793 // Eine einzelne Zeilen mit einem kombinierten Primärschlüssel finden
794 // Gibt ein Rowset zurück
795 $rows = $table->find(1234, 'ABC');
797 // Mehrere Zeilen mit einem kombinierten Primärschlüssel finden
798 // Gibt auch ein Rowset zurück
799 $rows = $table->find(array(1234, 5678), array('ABC', 'DEF'));
804 <sect2 id="zend.db.table.fetch-all">
805 <title>Ein Set von Zeilen abfragen</title>
807 <sect3 id="zend.db.table.fetch-all.select">
808 <title>Select API</title>
812 Die <acronym>API</acronym> für die Hol-Operationen wurde ausgeweitet um
813 einem <classname>Zend_Db_Table_Select</classname> Objekt zu erlauben die
814 Abfrage zu modifizieren. Trotzdem wird die veraltete Verwendung der
815 <methodname>fetchRow()</methodname> und <methodname>fetchAll()</methodname>
816 Methoden weiterhin ohne Änderungen funktionieren.
820 Die folgenden Ausdrücke sind gültig und funktionell identisch, trotzdem wird
821 empfohlen den Code zu aktualisieren um Vorteil aus der neuen Verwendung zu
822 ziehen wo das möglich ist.
825 <programlisting language="php"><![CDATA[
829 $rows = $table->fetchAll(
830 'bug_status = "NEW"',
835 $rows = $table->fetchAll(
837 ->where('bug_status = ?', 'NEW')
838 ->order('bug_id ASC')
842 $rows = $table->fetchAll(
844 ->where('bug_status = :status')
845 ->bind(array(':status'=>'NEW')
846 ->order('bug_id ASC')
851 * Eine einzelne Zeile holen
853 $row = $table->fetchRow(
854 'bug_status = "NEW"',
857 $row = $table->fetchRow(
859 ->where('bug_status = ?', 'NEW')
860 ->order('bug_id ASC')
863 $row = $table->fetchRow(
865 ->where('bug_status = :status')
866 ->bind(array(':status'=>'NEW')
867 ->order('bug_id ASC')
873 Das <classname>Zend_Db_Table_Select</classname> Objekt ist eine Erweiterung des
874 <classname>Zend_Db_Select</classname> Objekts das spezielle Einschränkungen zu einer
875 Abfrage hinzufügt. Die Verbesserungen und Einschränkungen sind folgende:
881 Man <emphasis>kann</emphasis> sich entscheiden ein Subset von Zeilen einer
882 fetchRow oder fetchAll Abfrage zurückzuerhalten. Dann kann Vorteile durch
883 Optimierung bieten, wenn die Rückgabe eines großes Sets an Ergebnissen für
884 alle Zeilen nicht gewünscht wird.
890 Man <emphasis>kann</emphasis> Zeilen spezifizieren die Ausdrücke innerhalb
891 der ausgewählten Tabelle evaluieren. Trotzdem bedeutet das, das die
892 zurückgegebene Zeile oder Zeilenset <property>readOnly</property> (nur
893 lesbar) ist und nicht für <methodname>save()</methodname> Operationen
894 verwendet werden kann. Eine <classname>Zend_Db_Table_Row</classname> mit
895 <property>readOnly</property> Status wird eine Exception werfen wenn eine
896 <methodname>save()</methodname> Operation versucht wird.
902 Man <emphasis>kann</emphasis> <constant>JOIN</constant> Klauseln auf einer
903 Auswahl erlauben um Mehrfach-Tabellen Lookups zu erlauben.
909 Man <emphasis>kann keine</emphasis> Spalten von einer geJOINten Tabelle
910 spezifizieren damit Sie in einer Zeile oder Zeilenset zurückgegeben werden.
911 Wenn das versucht wird, wird ein <acronym>PHP</acronym> Fehler getriggert.
912 Das wurde getan um Sicherzustellen das die Integrität von
913 <classname>Zend_Db_Table</classname> gewahrt bleibt. z.B. ein
914 <classname>Zend_Db_Table_Row</classname> sollte nur Spalten referenzieren
915 die von seiner Elterntabelle abgeleitet sind.
920 <example id="zend.db.table.qry.rows.set.simple.usage.example">
921 <title>Einfache Verwendung</title>
923 <programlisting language="php"><![CDATA[
926 $select = $table->select();
927 $select->where('bug_status = ?', 'NEW');
929 $rows = $table->fetchAll($select);
934 Flüssige Interfaces sind über alle Komponenten hinweg implementiert, sodass dies zu
935 einer abgekürzteren Form umgeschrieben werden kann.
938 <example id="zend.db.table.qry.rows.set.fluent.interface.example">
939 <title>Beispiel des Fluent Interfaces</title>
941 <programlisting language="php"><![CDATA[
945 $table->fetchAll($table->select()->where('bug_status = ?', 'NEW'));
950 <sect3 id="zend.db.table.fetch-all.usage">
951 <title>Ein Set von Zeilen abfragen</title>
954 Ein Set von Zeilen kann abgefragt werden indem irgendein Kriterium verwendet wird,
955 das anders als die Werte des Primärschlüssels sind, indem die
956 <methodname>fetchAll()</methodname> Methode der Tabellen Klasse verwendet wird.
957 Diese Methode gibt ein Objekt vom Typ
958 <classname>Zend_Db_Table_Rowset_Abstract</classname> zurück.
961 <example id="zend.db.table.qry.rows.set.finding.row.example">
962 <title>Beispiel für das Finden von Zeilen durch einen Ausdruck</title>
964 <programlisting language="php"><![CDATA[
967 $select = $table->select()->where('bug_status = ?', 'NEW');
969 $rows = $table->fetchAll($select);
974 Der <constant>ORDER</constant> BY kann auch ein Sortier-Kriterium übergeben werden,
975 genauso wie auch Count und Offset Integer Werte, verwendet werden können damit die
976 Abfrage ein spezielles Subset von Zeilen zurück gibt. Diese Werte werden in einer
977 <constant>LIMIT</constant> Klausel verwendet oder in einer ähnlichen Logik für
978 <acronym>RDBMS</acronym> Marken welche die <constant>LIMIT</constant> Syntax nicht
982 <example id="zend.db.table.fetch-all.example2">
983 <title>Beispiel für das Finden von Zeilen durch einen Ausdruck</title>
985 <programlisting language="php"><![CDATA[
990 // Gibt die Zeilen 21 bis 30 zurück
994 $select = $table->select()->where('bug_status = ?' => 'NEW')
996 ->limit($count, $offset);
998 $rows = $table->fetchAll($select);
1003 Alle diese Argumente sind optional. Wenn die <constant>ORDER</constant> Klausel
1004 unterdrückt wird, dann enthält das Ergebnis die Zeilen der Tabelle in einer
1005 unvorhersagbaren Reihenfolge. Wenn keine <constant>LIMIT</constant> Klausel gesetzt
1006 ist, dann wird jede Zeile dieser Tabelle zurückgegeben die der
1007 <constant>WHERE</constant> Klausen entspricht.
1011 <sect3 id="zend.db.table.advanced.usage">
1012 <title>Fortgeschrittene Verwendung</title>
1015 Für speziellere und optimierte Ergebnisse, kann es gewünscht sein die Anzahl der
1016 zurückgegebenen Zeilen oder Sets zu limitieren. Das kann durch die Übergabe einer
1017 <constant>FROM</constant> Klausel an das Select Objekt getan werden. Das erste
1018 Argument in der <constant>FROM</constant> Klausel ist identisch mit den des
1019 <classname>Zend_Db_Select</classname> Objekts wobei man zusätzlich eine Instanz von
1020 <classname>Zend_Db_Table_Abstract</classname> übergeben und damit den Tabellen Namen
1021 automatisch ermitteln lassen kann.
1024 <example id="zend.db.table.qry.rows.set.retrieving.a.example">
1025 <title>Spezielle Spalten erhalten</title>
1027 <programlisting language="php"><![CDATA[
1028 $table = new Bugs();
1030 $select = $table->select();
1031 $select->from($table, array('bug_id', 'bug_description'))
1032 ->where('bug_status = ?', 'NEW');
1034 $rows = $table->fetchAll($select);
1035 ]]></programlisting>
1040 Das Rowset enthält Zeilen die trotzdem 'gültig' sind - sie enthalten bloß
1041 ein Subset der Spalten einer Tabelle. Wenn eine <methodname>save()</methodname>
1042 Methode auf dem Teil einer Zeile aufgerufen wird dann werden nur die vorhandenen
1048 Es können Ausdrücke in einer <constant>FROM</constant> Klausel spezifiziert werden
1049 die dann als readOnly Zeile oder Set zurückgegeben werden. In diesem Beispiel werden
1050 Zeilen von der Bugs Tabelle zurückgegeben die einen Bereich von Nummern neuer Bugs
1051 zeigen die von Individuen mitgeteilt wurden. Die <constant>GROUP</constant> Klausel
1052 ist zu beachten. Die 'count' Spalte wird der Zeile für Evaluation angefügt und es
1053 kann auch Sie zugegriffen werden wie wenn Sie ein Teil des Schemas wäre.
1056 <example id="zend.db.table.qry.rows.set.retrieving.b.example">
1057 <title>Ausdrücke als Spalten erhalten</title>
1059 <programlisting language="php"><![CDATA[
1060 $table = new Bugs();
1062 $select = $table->select();
1063 $select->from($table,
1064 array('COUNT(reported_by) as `count`', 'reported_by'))
1065 ->where('bug_status = ?', 'NEW')
1066 ->group('reported_by');
1068 $rows = $table->fetchAll($select);
1069 ]]></programlisting>
1073 Es kann auch ein Lookup als Teil der Abfrage verwendet werden um die Fetch
1074 Operation zu verfeinern. In diesem Beispiel wird die Accounts Tabelle als Teil
1075 einer Suche nach allen Bugs die von 'Bob' gemeldet wurden, abgefragt.
1078 <example id="zend.db.table.qry.rows.set.refine.example">
1079 <title>Beispiel für das Finden von Zeilen durch einen Ausdruck</title>
1081 <programlisting language="php"><![CDATA[
1082 $table = new Bugs();
1084 // Bei gesetztem From Abschnitt empfangen, wichtig wenn gejoint werden soll
1085 $select = $table->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
1086 $select->setIntegrityCheck(false)
1087 ->where('bug_status = ?', 'NEW')
1088 ->join('accounts', 'accounts.account_name = bugs.reported_by')
1089 ->where('accounts.account_name = ?', 'Bob');
1091 $rows = $table->fetchAll($select);
1092 ]]></programlisting>
1096 <classname>Zend_Db_Table_Select</classname> wird primär verwendet um zu verbinden
1097 und zu prüfen um die Kriterien für einen legalen <constant>SELECT</constant> Query
1098 sicherzustellen. Trotzdem gibt es viele Fälle in denen man die Flexibilität der
1099 <classname>Zend_Db_Table_Row</classname> benötigt und Zeilen nicht geschrieben oder
1100 gelöscht werden müssen. Für diesen speziellen Fall ist es möglich Zeilen/-sets durch
1101 die Übergabe eines <constant>FALSE</constant> Wertes an
1102 <methodname>setIntegrityCheck()</methodname> zu erhalten. Das resultierende Zeilen
1103 oder Zeilenset wird als eine 'locked' Zeile zurückgegeben (das bedeutet das
1104 <methodname>save()</methodname>, <methodname>delete()</methodname> und jede andere
1105 Methode die Felder setzt wird eine Ausnahme werfen).
1108 <example id="zend.db.table.qry.rows.set.integrity.example">
1110 Entfernen des Integritäts Checks von Zend_Db_Table_Select um geJOINte Zeilen zu
1114 <programlisting language="php"><![CDATA[
1115 $table = new Bugs();
1117 $select = $table->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
1118 ->setIntegrityCheck(false);
1119 $select->where('bug_status = ?', 'NEW')
1121 'accounts.account_name= bugs.reported_by',
1123 ->where('accounts.account_name = ?', 'Bob');
1125 $rows = $table->fetchAll($select);
1126 ]]></programlisting>
1131 <sect2 id="zend.db.table.fetch-row">
1132 <title>Eine einzelne Zeilen abfragen</title>
1135 Eine einzelne Zeile kann abgefragt werden indem Kriterien verwendet werden die ähnlich
1136 denen der <methodname>fetchAll()</methodname> Methode sind.
1139 <example id="zend.db.table.fetch-row.example1">
1140 <title>Beispiel für das Finden einer einzelnen Zeilen durch einen Ausdruck</title>
1142 <programlisting language="php"><![CDATA[
1143 $table = new Bugs();
1145 $select = $table->select()->where('bug_status = ?', 'NEW')
1148 $row = $table->fetchRow($select);
1149 ]]></programlisting>
1153 Diese Methode gibt ein Objekt vom Typ <classname>Zend_Db_Table_Row_Abstract</classname>
1154 zurück. Wenn die spezifizierten Sortier-Kriterien keiner Zeile in der Datenbank Tabelle
1155 entsprechen gibt <methodname>fetchRow()</methodname> <acronym>PHP</acronym>'s
1156 <constant>NULL</constant> Wert zurück.
1160 <sect2 id="zend.db.table.info">
1161 <title>Informationen der Tabellen Metadaten erhalten</title>
1164 Die <classname>Zend_Db_Table_Abstract</classname> Klasse bietet einige Informationen
1165 über Ihre Metadaten. Die <methodname>info()</methodname> Methode gibt eine Array
1166 Struktur mit Informationen über die Tabelle, Ihre Spalten und Primärschlüssel zurück,
1167 sowie andere Metadaten.
1170 <example id="zend.db.table.info.example">
1171 <title>Beispiel für das Erhalten des Namens einer Tabelle</title>
1173 <programlisting language="php"><![CDATA[
1174 $table = new Bugs();
1176 $info = $table->info();
1178 echo "Der Name der Tabelle ist " . $info['name'] . "\n";
1179 ]]></programlisting>
1183 Die Schlüssel des Arrays das von der <methodname>info()</methodname> Methode
1184 zurückgegeben wird sind anbei beschrieben:
1190 <emphasis>name</emphasis> => der Name der Tabelle.
1196 <emphasis>cols</emphasis> => ein Array das die Spalte(n) der Tabelle benennt.
1202 <emphasis>primary</emphasis> => ein Array das die Spalte(n) des Primärschlüssels
1209 <emphasis>metadata</emphasis> => ein assoziatives Array das die Spaltennamen
1210 mit Informationen über die Spalten zusammenführt. Das ist die Information die
1211 durch die <methodname>describeTable()</methodname> Methode zurückgegeben wird.
1217 <emphasis>rowClass</emphasis> => der Name der konkreten Klasse die für
1218 Zeilen Objekte verwendet wird und von den Methoden dieser Table Instanz
1219 zurückgegeben wird. Der Standardwert ist
1220 <classname>Zend_Db_Table_Row</classname>.
1226 <emphasis>rowsetClass</emphasis> => Name der konkreten Klasse für für Rowset
1227 Objekte verwendet wird und von den Methoden dieser Table Instanz zurückgegeben
1228 wird. Der Standardwert ist <classname>Zend_Db_Table_Rowset</classname>.
1234 <emphasis>referenceMap</emphasis> => ist ein assoziatives Array von
1235 Klassennamen von Tabellen die diese Tabelle referenzieren. Siehe
1236 <link linkend="zend.db.table.relationships.defining">dieses Kapitel</link>.
1242 <emphasis>dependentTables</emphasis> => ein Array von Klassennamen von
1243 Tabellen die diese Tabelle referenzieren. Siehe
1244 <link linkend="zend.db.table.relationships.defining">dieses Kapitel</link>.
1250 <emphasis>schema</emphasis> => der Name des Schemas (oder der
1251 Datenbank oder dem Tabellenraum) für diese Tabelle.
1257 <sect2 id="zend.db.table.metadata.caching">
1258 <title>Tabellen Metadaten cachen</title>
1261 Standardmäßig fragt <classname>Zend_Db_Table_Abstract</classname> die darunterliegende
1262 Datenbank für die <link linkend="zend.db.table.info">Metadaten der Tabelle</link> ab
1263 immer wenn diese diese Daten benötigt werden um Tabellenoperationen durchzuführen. Das
1264 Tableobjekt holt die Metadaten der Tabelle von der Datenbank indem es die
1265 <methodname>describeTable()</methodname> Methode des Adapters verwendet. Operationen
1266 die diese Einsicht benötigten sind:
1270 <listitem><para><methodname>insert()</methodname></para></listitem>
1271 <listitem><para><methodname>find()</methodname></para></listitem>
1272 <listitem><para><methodname>info()</methodname></para></listitem>
1276 In einigen Fällen, speziell wenn viele Table Objekte auf der gleichen Datenbanktabelle
1277 instanziert werden kann das Abfragen der Datenbank nach den Metadaten der Tabelle für
1278 jede Instanz unerwünscht sein wegen der Geschwindigkeit. In solchen Fällen, können
1279 Benutzer davon profitieren das die Metadaten der Tabelle, die von der Datenbank
1280 empfangen werden, gecached werden.
1284 Es gibt zwei grundsätzliche Wege bei denen ein Benutzer Vorteile davon haben kann wenn
1285 die Metadaten der Tabelle gecached werden:
1291 <emphasis>Aufruf von
1292 <methodname>Zend_Db_Table_Abstract::setDefaultMetadataCache()</methodname></emphasis>
1293 - Das erlaubt es Entwicklern das Standardcacheobjekt zu setzen das für alle
1294 Tabellenklassen verwendet werden soll.
1300 <emphasis>Konfigurieren von
1301 <methodname>Zend_Db_Table_Abstract::__construct()</methodname></emphasis> -
1302 Das erlaubt es Entwicklern das Cacheobjekt zu setzen das für eine spezielle
1303 Instanz der Tabellenklasse verwendet werden soll.
1309 In beiden Fällen muß die Spezifikation des Caches entweder <constant>NULL</constant>
1310 (wenn kein Cache verwendet wird) oder eine Instanz von
1311 <link linkend="zend.cache.frontends.core"><classname>Zend_Cache_Core</classname></link>
1312 sein. Die Methoden können in Verbindung zueinander verwendet werden wenn es gewünscht
1313 ist beides zu haben, einen standardmäßigen Cache für die Metadaten und die Möglichkeit
1314 den Cache eines individuellen Tabellenobjektes zu ändern.
1317 <example id="zend.db.table.metadata.caching-default">
1319 Verwenden eines standardmäßigen Caches für Metadaten für alle Tabellenobjekte
1323 Der folgende Code demonstriert wie ein standardmäßiger Cache für die Metadaten
1324 gesetzt werden kann der für alle Tabellenobjekte verwendet wird:
1327 <programlisting language="php"><![CDATA[
1328 // Zuerst muß der Cache vorbereitet werden
1329 $frontendOptions = array(
1330 'automatic_serialization' => true
1333 $backendOptions = array(
1334 'cache_dir' => 'cacheDir'
1337 $cache = Zend_Cache::factory('Core',
1342 // Als nächstes, den Cache setzen der mit allen Tabellenobjekten verwendet werden soll
1343 Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
1345 // Eine Tabellenklasse wird auch benötigt
1346 class Bugs extends Zend_Db_Table_Abstract
1351 // Jede Instanz von Bugs verwenden nur den Standardmäßigen Cache für die Metadaten
1353 ]]></programlisting>
1356 <example id="zend.db.table.metadata.caching-instance">
1357 <title>Einen Metadaten Cache für ein spezielles Tabellenobjekt verwenden</title>
1360 Der folgende Code demonstriert wie ein Cache für Metadaten für eine spezielle
1361 Instanz eines Tabellenobjektes gesetzt werden kann:
1364 <programlisting language="php"><![CDATA[
1365 // Zuerst den Cache vorbereiten
1366 $frontendOptions = array(
1367 'automatic_serialization' => true
1370 $backendOptions = array(
1371 'cache_dir' => 'cacheDir'
1374 $cache = Zend_Cache::factory('Core',
1379 // Eine Tabellenklasse wird auch benötigt
1380 class Bugs extends Zend_Db_Table_Abstract
1385 // Eine Instanz für die Instanzierung konfgurieren
1386 $bugs = new Bugs(array('metadataCache' => $cache));
1387 ]]></programlisting>
1391 <title>Automatische Serialisierung mit dem Cache Frontend</title>
1394 Da die Information die von der <methodname>describeTable()</methodname> Methode des
1395 Adapters zurückgegeben wird, ein Array ist, muß sichergestellt werden das die
1396 <property>automatic_serialization</property> Option für das
1397 <classname>Zend_Cache_Core</classname> Frontend auf <constant>TRUE</constant>
1403 Obwohl die obigen Beispiele <classname>Zend_Cache_Backend_File</classname> verwenden,
1404 können Entwickler jegliches Cache Backend verwenden das der Situation am besten
1405 entspricht. Siehe <link linkend="zend.cache">Zend_Cache</link> für weitere
1409 <sect3 id="zend.db.table.metadata.caching.hardcoding">
1410 <title>Tabellen Metadaten hardcoden</title>
1413 Um das Cachen von Metadaten einen weiteren Schritt weiterzubringen, kann man sich
1414 auch entscheiden die Metadaten hardzucoden. In diesem speziellen Fall benötigt jede
1415 Änderung trotzdem eine Änderung im Code. Als solches, ist es nur empfohlen für jene
1416 die eine Produktionsumgebung optimieren wollen.
1420 Die Struktur der Metadaten ist wie folgt:
1423 <programlisting language="php"><![CDATA[
1424 protected $_metadata = array(
1425 '<column_name>' => array(
1426 'SCHEMA_NAME' => <string>,
1427 'TABLE_NAME' => <string>,
1428 'COLUMN_NAME' => <string>,
1429 'COLUMN_POSITION' => <int>,
1430 'DATA_TYPE' => <string>,
1431 'DEFAULT' => NULL|<value>,
1432 'NULLABLE' => <bool>,
1433 'LENGTH' => <string - length>,
1434 'SCALE' => NULL|<value>,
1435 'PRECISION' => NULL|<value>,
1436 'UNSIGNED' => NULL|<bool>,
1437 'PRIMARY' => <bool>,
1438 'PRIMARY_POSITION' => <int>,
1439 'IDENTITY' => <bool>,
1441 // additional columns...
1443 ]]></programlisting>
1446 Ein einfacher Weg um die richtigen Werte zu erhalten ist es den Metadaten Cache zu
1447 verwenden, und dann die Werte die im Cache gespeichert sind, zu deserialisieren.
1451 Diese Optimierung kann ausgeschaltet werden indem das
1452 <property>metadataCacheInClass</property> Flag ausgeschaltet wird:
1455 <programlisting language="php"><![CDATA[
1456 // Bei der Instanziierung:
1457 $bugs = new Bugs(array('metadataCacheInClass' => false));
1460 $bugs->setMetadataCacheInClass(false);
1461 ]]></programlisting>
1464 Das Flag ist standardmäßig aktiviert, was sicherstellt dass das
1465 <varname>$_metadata</varname> Array nur einmal pro Instanz ausgeliefert wird.
1470 <sect2 id="zend.db.table.extending">
1471 <title>Eine Table Klasse erweitern und anpassen</title>
1473 <sect3 id="zend.db.table.extending.row-rowset">
1474 <title>Verwenden eigener Zeilen oder Rowset Klassen</title>
1477 Standardmäßig geben die Methoden der Table Klasse ein Rowset als Instanzen der
1478 konkreten Klasse <classname>Zend_Db_Table_Rowset</classname>, und Rowsets enthalten
1479 eine Kollektion von Instanzen der konkreten Klasse
1480 <classname>Zend_Db_Table_Row</classname>. Eine alternative Klasse kann für jede von
1481 Ihnen als alternative Klasse definiert werden die verwendet werden soll, aber es
1482 müssen Klassen sein die <classname>Zend_Db_Table_Rowset_Abstract</classname>
1483 erweitern und respektiv <classname>Zend_Db_Table_Row_Abstract</classname>.
1487 Es können Zeilen und Rowset Klassen definiert werden indem das Optionsarray des
1488 Table Konstruktors verwendet wird, respektiv die Schlüssel
1489 '<property>rowClass</property>' und '<property>rowsetClass</property>'. Die Namen
1490 der Klassen müssen spezifiziert werden indem Strings verwendet werden.
1493 <example id="zend.db.table.extending.row-rowset.example">
1495 Beispiel dafür wie die Zeilen und Rowset Klassen spezifiziert werden können
1498 <programlisting language="php"><![CDATA[
1499 class My_Row extends Zend_Db_Table_Row_Abstract
1504 class My_Rowset extends Zend_Db_Table_Rowset_Abstract
1511 'rowClass' => 'My_Row',
1512 'rowsetClass' => 'My_Rowset'
1516 $where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
1518 // Gibt ein Objekt des Typs My_Rowset zurück
1519 // das ein Array von Objekten des Typs My_Row enthält.
1520 $rows = $table->fetchAll($where);
1521 ]]></programlisting>
1525 Die Klassen können geändert werden indem Sie mit den
1526 <methodname>setRowClass()</methodname> und
1527 <methodname>setRowsetClass()</methodname> Methoden spezifiziert werden. Das
1528 entspricht den Zeilen und Rowsets die nachfolgend erstellt werden; es ändert aber
1529 nicht die Klasse von Zeilen- oder Rowsetobjekten die bereits davor erstellt wurden.
1532 <example id="zend.db.table.extending.row-rowset.example2">
1533 <title>Beispiel für das Ändern von Zeilen und Rowset Klassen</title>
1535 <programlisting language="php"><![CDATA[
1536 $table = new Bugs();
1538 $where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
1540 // Gibt ein Objekt vom Typ Zend_Db_Table_Rowset zurück das ein Array
1541 // von Objekten des Typs Zend_Db_Table_Row enthält.
1542 $rowsStandard = $table->fetchAll($where);
1544 $table->setRowClass('My_Row');
1545 $table->setRowsetClass('My_Rowset');
1547 // Gibt ein Objekt vom Typ My_Rowset zurück das ein Array
1548 // von Objekten des Typs My_Row enthält.
1549 $rowsCustom = $table->fetchAll($where);
1551 // Das $rowsStandard Objekt existiert noch immer, und es bleibt unverändert.
1552 ]]></programlisting>
1556 Für weitere Informationen über Zeilen und Rowset Klassenm siehe
1557 <link linkend="zend.db.table.row">dieses Kapitel</link> und <link
1558 linkend="zend.db.table.rowset">dieses hier</link>.
1562 <sect3 id="zend.db.table.extending.insert-update">
1563 <title>Selbst definierte Logik für das Einfügen, Aktualisieren und Löschen</title>
1566 Die <methodname>insert()</methodname> und <methodname>update()</methodname>
1567 Methoden in der Table Klasse können überschrieben werden. Das bietet die
1568 Möglichkeit eigenen Code einzufügen der ausgeführt wird bevor die Datenbank
1569 Operation durchgeführt wird. Es muß sichergestellt werden das die Methode der
1570 Elternklasse aufgerufen wird wenn man fertig ist.
1573 <example id="zend.db.table.extending.insert-update.example">
1574 <title>Eigene Logik um Zeitstempel zu managen</title>
1576 <programlisting language="php"><![CDATA[
1577 class Bugs extends Zend_Db_Table_Abstract
1579 protected $_name = 'bugs';
1581 public function insert(array $data)
1583 // Einen Zeitstempel hinzufügen
1584 if (empty($data['created_on'])) {
1585 $data['created_on'] = time();
1587 return parent::insert($data);
1590 public function update(array $data, $where)
1592 // Einen Zeitstempel hinzufügen
1593 if (empty($data['updated_on'])) {
1594 $data['updated_on'] = time();
1596 return parent::update($data, $where);
1599 ]]></programlisting>
1603 Auch die <methodname>delete()</methodname> Methode kann überschrieben werden.
1607 <sect3 id="zend.db.table.extending.finders">
1608 <title>Eigene Such Methoden in Zend_Db_Table definieren</title>
1611 Es können eigene Abfrage Methoden in der Table Klasse implementiert werden, wenn oft
1612 die Notwendigkeit besteht Abragen mit speziellen Kriterien auf der Table Klasse
1613 durchzuführen. Die meisten Abfragen können mit <methodname>fetchAll()</methodname>
1614 geschrieben werden, das bedeutet aber das Code dupliziert werden muß um
1615 Abfragekonditionen zu formen die Abfrage in verschiedenen Orten der Anwendung
1616 auszuführen. Hierfür kann es nützlich sein eine Methode in der Table Klasse zu
1617 definieren um oft benutzte Abfragen an dieser Tabelle durchzuführen.
1620 <example id="zend.db.table.extending.finders.example">
1621 <title>Eigene Methode um Fehler durch den Status zu finden</title>
1623 <programlisting language="php"><![CDATA[
1624 class Bugs extends Zend_Db_Table_Abstract
1626 protected $_name = 'bugs';
1628 public function findByStatus($status)
1630 $where = $this->getAdapter()->quoteInto('bug_status = ?', $status);
1631 return $this->fetchAll($where, 'bug_id');
1634 ]]></programlisting>
1638 <sect3 id="zend.db.table.extending.inflection">
1639 <title>Inflection (Beugung) in Zend_Db_Table definieren</title>
1642 Einige Leute bevorzugen das der Name der Table Klasse einem Tabellennamen in der
1643 <acronym>RDBMS</acronym>, durch eine Stringumwandlung die
1644 <emphasis>Inflection</emphasis> (Beugung) genannt wird, entspricht.
1648 Wenn zum Beispiel der Name der Table Klasse "BugsProducts" ist, würde
1649 Sie der physikalischen Tabelle in der Datenbank entsprechen die
1650 "bugs_products" heißt, wenn die explizite Definition der
1651 <varname>$_name</varname> Eigenschaft der Klasse unterdrückt wird. In dieser
1652 Übereinstimmung der Beugung, wird der Klassenname im "CamelCase" Format geschrieben
1653 und in Kleinschreibung transformiert, und Wörter mit einem Unterstrich seperiert.
1657 Der Tabellenname der Datenbank kann unabhängig vom Klassennamen spezifiziert werden
1658 indem der Tabellenname mit der Klasseneigenschaft <varname>$_name</varname> in jeder
1659 der eigenen Tabellenklassen deklariert wird.
1663 <classname>Zend_Db_Table_Abstract</classname> führt keine Beugung durch um die
1664 Klassennamen mit den Tabellennamen in Übereinstimmung zu bringen. Wenn die
1665 Deklaration von <varname>$_name</varname> in der eigenen Tabellenklasse unterdrückt
1666 wird, wird die Klasse mit der Datenbanktabelle in Verbindung gebracht die der
1667 Schreibweise des Klassennamens exakt entspricht.
1671 Es ist unzureichend Identifizierer von der Datenbank zu transformieren, da das zu
1672 Doppeldeutigkeiten führen kann oder einige Identifizierer sogar unerreichbar macht.
1673 Die Verwendung der <acronym>SQL</acronym> Identifizierer exakt so wie Sie in der
1674 Datenbank vorhanden sind, macht <classname>Zend_Db_Table_Abstract</classname> sowohl
1675 einfacher als auch flexibler.
1679 Wenn man es vorzieht Beugung zu verwenden, muß die Transformation selbst durch das
1680 Überschreiben der <methodname>_setupTableName()</methodname> Methode in der eigenen
1681 Tabellenklasse implementiert werden. Ein Weg um das zu tun ist die Definition einer
1682 abstrakten Klase die <classname>Zend_Db_Table_Abstract</classname> erweitert. Der
1683 Rest der eigenen Klassen erweitert dann die eigene neue abstrakte Klasse.
1686 <example id="zend.db.table.extending.inflection.example">
1687 <title>Beispiel einer abstrakten Tabellenklasse die Beugung implementiert</title>
1689 <programlisting language="php"><![CDATA[
1690 abstract class MyAbstractTable extends Zend_Db_Table_Abstract
1692 protected function _setupTableName()
1694 if (!$this->_name) {
1695 $this->_name = myCustomInflector(get_class($this));
1697 parent::_setupTableName();
1701 class BugsProducts extends MyAbstractTable
1704 ]]></programlisting>
1708 Man ist selbst für das Schreiben von Funktionen verantwortlich um die Transformation
1709 der Beugung auszuführen. Zend Framework bietet solche Funktionen nicht an.