| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 15851 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.db.table">
- <title>Zend_Db_Table</title>
- <sect2 id="zend.db.table.introduction">
- <title>Einführung</title>
- <para>
- Die <classname>Zend_Db_Table</classname> Klasse ist eine Objekt-Orientierte
- Schnittstelle zu Datenbank Tabellen. Sie bietet Methoden für viele gängige Operationen
- an Tabellen. Die Basisklasse ist erweiterbar, daher kann eigene Logik eingeführt werden.
- </para>
- <para>
- Die <classname>Zend_Db_Table</classname> Lösung ist eine Implementation des
- <ulink url="http://www.martinfowler.com/eaaCatalog/tableDataGateway.html">Table Data
- Gateway</ulink> Patterns. Die Lösung schließt außerdem eine Klasse ein, welche das
- <ulink url="http://www.martinfowler.com/eaaCatalog/rowDataGateway.html">Row Data
- Gateway</ulink> Pattern implementiert.
- </para>
- </sect2>
- <sect2 id="zend.db.table.defining">
- <title>Definieren einer Table Klasse</title>
- <para>
- Für jede Tabelle der Datenbank auf die zugegriffen werden soll, sollte eine eine Klasse
- erzeugt werden, welche <classname>Zend_Db_Table_Abstract</classname> erweitert.
- </para>
- <sect3 id="zend.db.table.defining.table-schema">
- <title>Definieren des Tabellennamens und Schemas</title>
- <para>
- Die Tabelle der Datenbank, für welche die Klasse bestimmt ist, wird mit der
- protected Variablen <varname>$_name</varname> angegeben. Es ist ein String, welcher den
- Namen der Tabelle enthalten muss, wie er in der Datenbank erscheint.
- </para>
- <example id="zend.db.table.defining.table-schema.example1">
- <title>Angeben einer Table Klasse mit ausdrücklichem Tabellennamen</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- }
- ]]></programlisting>
- </example>
- <para>
- Wird keine Tabellenname angegeben, so wird ein Standard verwendet, welcher dem
- Namen der Klasse entspricht. Wird sich auf diesen Standard verlassen, so muss der
- Klassenname der Schreibweise der Tabelle entsprechen, wie sie in der Datenbank
- erscheint.
- </para>
- <example id="zend.db.table.defining.table-schema.example">
- <title>Angeben einer Table Klasse mit inbegriffenem Tabellennamen</title>
- <programlisting language="php"><![CDATA[
- class bugs extends Zend_Db_Table_Abstract
- {
- // Tabellenname entspricht dem Klassennamen
- }
- ]]></programlisting>
- </example>
- <para>
- Es kann auch ein Schema für die Tabelle angegeben werden. Entweder mit der protected
- Variablen <varname>$_schema</varname> oder mit dem Schema vorangestellt in der
- <varname>$_name</varname> Eigenschaft. Jedes Schema welches in der <varname>$_name</varname>
- Eigenschaft angegeben ist wird vorrangig gegenüber dem Schema der
- <varname>$_schema</varname> Eigenschaft behandelt. In einigen RDBMS Marken ist die
- Bezeichnung für Schema "database" oder "tablespace", wird aber ähnlich verwendet.
- </para>
- <example id="zend.db.table.defining.table-schema.example3">
- <title>Angeben einer Table Klasse mit Schema</title>
- <programlisting language="php"><![CDATA[
- // Erste Möglichkeit:
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_schema = 'bug_db';
- protected $_name = 'bugs';
- }
- // Zweite Möglichkeit:
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bug_db.bugs';
- }
- // Wenn Schema sowohl in $_name als auch $_schema angegeben wird, so bekommt $_name vorrang:
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bug_db.bugs';
- protected $_schema = 'ignored';
- }
- ]]></programlisting>
- </example>
- <para>
- Die Schema und Tabellennamen können auch mit Konstruktor Konfigurationsdirektiven
- angegeben werden, welche jegliche Standardwerte, angegeben in den
- <varname>$_name</varname> und <varname>$_schema</varname> Eigenschaften, überschreiben. Eine
- Schema Angabe welche mit der <code>name</code> Directive angegeben wurde
- überschreibt jeglichen Wert welcher von der <code>schema</code> Option
- bereitgestellt ist.
- </para>
- <example id="zend.db.table.defining.table-schema.example.constructor">
- <title>Angebend von Tabellen und Schemanamen während der Instanziierung</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- }
- // Erste Möglichkeit:
- $tableBugs = new Bugs(array('name' => 'bugs', 'schema' => 'bug_db'));
- // Zweite Möglichkeit:
- $tableBugs = new Bugs(array('name' => 'bug_db.bugs'));
- // Wenn Schema sowohl in $_name als auch $_schema angegeben wird,
- // so bekommt $_name vorrang:
- $tableBugs = new Bugs(array('name' => 'bug_db.bugs',
- 'schema' => 'ignored'));
- ]]></programlisting>
- </example>
- <para>
- Wenn kein Schemaname angegeben wird, so wird als Standard der Schemaname des
- Datenbankadapters verwendet.
- </para>
- </sect3>
- <sect3 id="zend.db.table.defining.primary-key">
- <title>Angeben des Primärschlüssels der Tabelle</title>
- <para>
- Jede Tabelle muss einen Primärschlüssel haben. Die Spalte des Primärschlüssels kann
- mit der protected Variablen <varname>$_primary</varname> angegeben werden. Sie enthält
- entweder einen String, welcher die einzelen Spalte benennt, oder ein Array von
- Spaltennamen, wenn der Primärschlüssel ein zusammengesetzter Schlüssel ist.
- </para>
- <example id="zend.db.table.defining.primary-key.example">
- <title>Beispiel für das spezifizieren eines Primärschlüssels</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- protected $_primary = 'bug_id';
- }
- ]]></programlisting>
- </example>
- <para>
- Wenn kein Primärschlüssel angegeben wird, versucht
- <classname>Zend_Db_Table_Abstract</classname> den Primärschlüssel mit Hilfe der
- <code>describeTable()</code> Methode zu ermitteln.
- </para>
- <note>
- <para>
- Jede Table Klasse muss wissen mit welche(r/n) Spalte(n) Zeilen eindeutig
- identifiziert werden können. Wenn keine Primärschlüssel Spalte(n) in der
- Klassendefinition oder als Argument für den Konstruktor angegeben wurde und
- nicht aus den Metadaten der Tabelle mit Hilfe der <code>describeTable()</code>
- Methode ermittelt werden kann, dann kann die Tabelle nicht mit
- <classname>Zend_Db_Table</classname> verwendet werden.
- </para>
- </note>
- </sect3>
- <sect3 id="zend.db.table.defining.setup">
- <title>Überschreiben von Table Setup Methoden</title>
- <para>
- Wenn eine Instanz einer Table Klasse erzeugt wird, ruft der Konstruktor einige
- protected Methoden auf, die Metadaten der Tabelle initialisieren. Jede dieser
- Methoden kann erweitert werden um Metadaten explizit anzugeben. Dabei darf nicht
- vergessen werden am Ende der eigenen Methode die gleichnamige Methode der
- Parentklasse aufzurufen.
- </para>
- <example id="zend.db.table.defining.setup.example">
- <title>Beispiel für das Überschreiben der _setupTableName() Methode</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected function _setupTableName()
- {
- $this->_name = 'bugs';
- parent::_setupTableName();
- }
- }
- ]]></programlisting>
- </example>
- <para>
- Folgende Setup Methoden sind überschreibbar:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <code>_setupDatabaseAdapter()</code> überprüft ob ein Adapter bereitgestellt
- wird; nimmt einen Standardadapter aus der Registry, wenn benötigt. Durch das
- Überschreiben dieser Methode kann ein Datenbankadapter aus einer anderen
- Quelle gesetzt werden.
- </para>
- </listitem>
- <listitem>
- <para>
- <code>_setupTableName()</code> setzt den standard Tabellennamen auf den
- Namen der Klasse. Durch das Überschreiben dieser Methode kann der
- Tabellenname gesetzt werden bevor dieses Standardverhalten abläuft.
- </para>
- </listitem>
- <listitem>
- <para>
- <code>_setupMetadata()</code> setzt das Schema wenn der Tabellenname dem
- Muster "schema.table" entspricht; ruft <code>describeTable()</code> auf um
- Metadaten Informationen zu erhalten; Standardisiert das <varname>$_cols</varname>
- Array auf die Spalten wie von <code>describeTable()</code> geliefert. Durch
- das Überschreiben dieser Methode können die Spalten angegeben werden.
- </para>
- </listitem>
- <listitem>
- <para>
- <code>_setupPrimaryKey()</code> standardisiert die Primärschlüssel Spalten
- zu denen geliefert von <code>describeTable()</code>; prüft ob die
- Primärschlüssel Spalten im <varname>$_cols</varname> Array enthalten sind. Durch
- das Überschreiben dieser Methode können die Primärschlüssel Spalten
- angegeben werden.
- </para>
- </listitem>
- </itemizedlist>
- </sect3>
- <sect3 id="zend.db.table.initialization">
- <title>Tabellen Initialisierung</title>
- <para>
- Wenn Anwendungs-spezifische Logik initialisiert werden soll wenn eine Tabellenklasse
- erstellt wird, kann man entscheiden die Aufgaben in die <code>init()</code> Methode
- zu verschieben, die aufgerufen wird nachdem alle Tabellen Metadaten bearbeitet
- wurden. Das ist besser als die <code>__construct</code> Methode wenn die Metadaten
- nicht programmtechnisch verändert werden sollen.
- </para>
- <example id="zend.db.table.defining.init.usage.example">
- <title>Beispielverwendung der init() Methode</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_observer;
- public function init()
- {
- $this->_observer = new MyObserverClass();
- }
- }
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.db.table.constructing">
- <title>Erzeugen einer Instanz einer Tabelle</title>
- <para>
- Bevor eine Table Klasse verwendet werden kann muss eine Instanz mit dem Konstruktor
- erzeugt werden. Das Konstruktor Argument ist ein Array von Optionen. Die wichtigste
- Option für einen Tabellenkonstruktor ist die Instanz der Adapterklasse, welche eine live
- Verbindung zu einem RDBMS repräsentiert. Es gibt drei Möglichkeiten den Datenbankadapter
- einer Tabellenklasse anzugeben und diese sind unten beschrieben:
- </para>
- <sect3 id="zend.db.table.constructing.adapter">
- <title>Angeben eines Datenbankadapters</title>
- <para>
- Der erste Weg einen Datenbankadapter an eine Table Klasse bereitzustellen ist, ein
- Objekt des Typs <classname>Zend_Db_Adapter_Abstract</classname> im Options Array,
- bezeichnet mit dem Schlüssel <code>'db'</code>, zu übergeben.
- </para>
- <example id="zend.db.table.constructing.adapter.example">
- <title>
- Beispiel für das Erzeugen einer Tabelle mit Nutzung eines Adapterobjekts
- </title>
- <programlisting language="php"><![CDATA[
- $db = Zend_Db::factory('PDO_MYSQL', $options);
- $table = new Bugs(array('db' => $db));
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.table.constructing.default-adapter">
- <title>Setzen eines Standard-Datenbankadapters</title>
- <para>
- Der zweite Weg einer Table Klasse einen Datenbankadapter bereit zu stellen ist es,
- ein Objekt des Typs <classname>Zend_Db_Adapter_Abstract</classname> zu deklarieren
- und als Standard für alle nachfolgenden Instanzen von Table der Applikation zu
- setzen. Dies kann mit der static Methode
- <classname>Zend_Db_Table_Abstract::setDefaultAdapter()</classname> getan werden. Das
- Argument ist ein Objekt des Typs <classname>Zend_Db_Adapter_Abstract</classname>.
- </para>
- <example id="zend.db.table.constructing.default-adapter.example">
- <title>Beispiel für das erstellen von Table mit einem Standardadapter</title>
- <programlisting language="php"><![CDATA[
- $db = Zend_Db::factory('PDO_MYSQL', $options);
- Zend_Db_Table_Abstract::setDefaultAdapter($db);
- // Später...
- $table = new Bugs();
- ]]></programlisting>
- </example>
- <para>
- Es kann geeignet sein den Datenbankadapter an einer zentralen Stelle der Anwendung,
- wie dem Bootstrap, zu erzeugen, und als Standardadapter zu speichern. Dies hilft
- sicher zu stellen, das der verwendete Adapter in der gesamten Anwendung der gleiche
- ist. Allerdings kann nur eine einzelne Adapterinstanz als Standardadapter verwendet
- werden.
- </para>
- </sect3>
- <sect3 id="zend.db.table.constructing.registry">
- <title>Speichern eines Datenbankadapters in der Registry</title>
- <para>
- Der dritte Weg einer Table Klasse einen Datenbankadapter bereit zu stellen ist es
- einen String in dem Optionsarray zu übergeben, auch mit dem <code>'db'</code>
- Schlüssel identifiziert. Der String wird als Schlüssel der statischen
- <classname>Zend_Registry</classname> Instanz verwendet, wo der Eintrag mit dem
- Schlüssel ein Objekt des Typs <classname>Zend_Db_Adapter_Abstract</classname> ist.
- </para>
- <example id="zend.db.table.constructing.registry.example">
- <title>Beispiel für das Erzeugen von Table mit einem Registry Schlüssel</title>
- <programlisting language="php"><![CDATA[
- $db = Zend_Db::factory('PDO_MYSQL', $options);
- Zend_Registry::set('my_db', $db);
- // Später...
- $table = new Bugs(array('db' => 'my_db'));
- ]]></programlisting>
- </example>
- <para>
- Wie das Setzen eines Standardadapters, bietet auch dieses sicher zu stellen das die
- gleiche Adapter Instanz in der gesamten Anwendung verwendet wird. Nutzen der
- Registry ist flexibler, da mehr als eine Adapterinstanz gepeichert werden kann. Eine
- angegebene Adapterinstanz ist spezifisch für eine bestimmte RDBMS Marke und
- Datenbankinstanz. Wenn die Anwendung Zugriff auf mehrere Datenbanken benötigt oder
- auch mehrere Datenbank Marken, dann müssen mehrere Adapter verwendet werden.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.table.insert">
- <title>Zeilen in eine Tabelle einfügen</title>
- <para>
- Table Objekte können verwendet werden um Zeilen in die Datenbank Tabelle einzufügen auf
- der das Table Objekt basiert. Hierzu kann die <code>insert()</code> Methode des Table
- Objektes verwendet werden. Das Argument ist ein assoziatives Array, das Spalten Namen
- mit Werten verbindet.
- </para>
- <example id="zend.db.table.insert.example">
- <title>Beispiel für das Einfügen in eine Tabelle</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $data = array(
- 'created_on' => '2007-03-22',
- 'bug_description' => 'Irgendwas falsch',
- 'bug_status' => 'NEW'
- );
- $table->insert($data);
- ]]></programlisting>
- </example>
- <para>
- Standardmäßig werden Werte im Daten Array als literale Werte eingefügt durch das
- Verwenden von Parametern. Wenn es notwendig ist das diese als SQL Ausdruck behandelt
- werden, muß sichergestellt werden das Sie sich von reinen Strings unterscheiden. Es kann
- ein Objekt vom Typ <classname>Zend_Db_Expr</classname> verwendet werden um das zu
- bewerkstelligen.
- </para>
- <example id="zend.db.table.insert.example-expr">
- <title>Beispiel für das Einfügen von Ausdrücken in einer Tabelle</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $data = array(
- 'created_on' => new Zend_Db_Expr('CURDATE()'),
- 'bug_description' => 'Irgendwas ist falsch',
- 'bug_status' => 'NEU'
- );
- ]]></programlisting>
- </example>
- <para>
- Um obigen Beispiel vom Einfügen von Zeilen, wird angenommen das die Tabelle einen automatischen
- Primärschlüssel hat. Das ist das Standardverhalten von <classname>Zend_Db_Table_Abstract</classname>,
- aber es gibt auch andere Typen von Primärschlüssel. Das folgende Kapitel beschreibt wie
- verschiedene Typen von Primärschlüssel unterstützt werden.
- </para>
- <sect3 id="zend.db.table.insert.key-auto">
- <title>Eine Tabelle mit einem automatischen Primärschlüssel verwenden</title>
- <para>
- Ein automatischer Primärschlüssel erzeigt einen eindeutigen Integerwert wenn die
- Spalte des Primären Typs in der eigenen SQL <code>INSERT</code> Anweisung unterdrückt wird.
- </para>
- <para>
- Wenn die geschützte Variable <varname>$_sequence</varname>, in <classname>Zend_Db_Table_Abstract</classname>, als
- boolscher Wert <constant>TRUE</constant> definiert wird, nimmt die Klasse an das die Tabelle
- einen automatischen Primärschlüssel hat.
- </para>
- <example id="zend.db.table.insert.key-auto.example">
- <title>
- Beispiel für das Deklarierens einer Tabelle mit einem automatischen
- Primärschlüssel
- </title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- // Das ist der Standardwert in der Zend_Db_Table_Abstract Klasse;
- // er muß nicht definiert werden.
- protected $_sequence = true;
- }
- ]]></programlisting>
- </example>
- <para>
- MySQL, Microsoft SQL Server, und SQLite sind Beispiele von RDBMS Marken die
- automatische Primärschlüssel unterstützen.
- </para>
- <para>
- PostgreSQL hat eine <code>SERIAL</code> Notation die implizit eine Sequenz definiert
- die auf den Tabellen- und Spaltennamen basiert, und diese Sequenz verwendet, um
- einen Schlüsselwert für neue Zeilen zu erstellen. IBM DB2 hat eine
- <code>IDENTITY</code> Notation die ähnlich arbeitet. Wenn eine dieser Notationen
- verwendet wird, muß der <classname>Zend_Db_Table</classname> Klasse mitgeteilt
- werden das Sie eine automatische Spalte hat, indem <varname>$_sequence</varname> auf
- <constant>TRUE</constant> gesetzt wird.
- </para>
- </sect3>
- <sect3 id="zend.db.table.insert.key-sequence">
- <title>Eine Tabelle mit einer Sequenz verwenden</title>
- <para>
- Eine Sequenz ist ein Datenbank Objekt das einen eindeutigen Wert erstellt, der als
- Wert des Primärschlüssels in einer oder mehreren Tabellen der Datenbank verwendet
- werden kann.
- </para>
- <para>
- Wenn <varname>$_sequence</varname> als String definiert wird, nimmt
- <classname>Zend_Db_Table_Abstract</classname> an das der String den Namen des
- Sequenz Objektes in der Datenbank benennt. Die Sequenz wird aufgerufen um einen
- neuen Wert zu erstellen, und dieser Wert wird in der <code>INSERT</code> Operation
- verwendet.
- </para>
- <example id="zend.db.table.insert.key-sequence.example">
- <title>Beispiel für das Deklaration einer Tabelle mit einer Sequenz</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- protected $_sequence = 'bug_sequence';
- }
- ]]></programlisting>
- </example>
- <para>
- Oracle, PostgreSQL, und IBM DB2 sind Beispiele von RDBMS Marken die Sequenz Objekte
- in der Datenbank unterstützen.
- </para>
- <para>
- PostgreSQL und IBM DB2 haben auch einen Syntax der Sequenzen implizit definiert und
- diese mit Spalten assoziiert. Wenn diese Notation verwendet wird, muß der Tabelle
- gesagt werden das Sie eine automatische Schlüsselspalte besitzt. Der Name der
- Sequenz muß nur in den Fällen als String definiert werden in denen die Sequenz
- explizit aufgerufen wird um den nächsten Schlüsselwert zu erhalten.
- </para>
- </sect3>
- <sect3 id="zend.db.table.insert.key-natural">
- <title>Eine Tabelle mit einem natürlichen Schlüssel verwenden</title>
- <para>
- Einige Tabellen haben natürliche Schlüssel. Das bedeutet das der Schlüssel nicht
- automatisch durch die Tabelle oder eine Sequenz erstellt wird. Der Wert für den
- Primärschlüssel muß in diesem Fall selbst definiert werden.
- </para>
- <para>
- Wenn <varname>$_sequence</varname> als boolsches <constant>FALSE</constant> definiert wird, nimmt
- <classname>Zend_Db_Table_Abstract</classname> an das die Tabelle einen natürlichen
- Primärschlüssel hat. Es müssen Werte für die Spalte des Primärschlüssels im Array
- der Daten definiert werden die an die <code>insert()</code> Methode übergeben
- werden, andernfalls wird diese Methode eine
- <classname>Zend_Db_Table_Exception</classname> werfen.
- </para>
- <example id="zend.db.table.insert.key-natural.example">
- <title>
- Beispiel für das Definieren einer Tabelle mit einem natürlichen Schlüssel
- </title>
- <programlisting language="php"><![CDATA[
- class BugStatus extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bug_status';
- protected $_sequence = false;
- }
- ]]></programlisting>
- </example>
- <note>
- <para>
- Alle RDBMS Marken unterstützen Tabellen mit natürlichen Schlüsseln. Beispiele
- von Tabellen die oft so definiert werden das Sie natürliche Schlüssel besitzen
- sind Lookup Tabellen, Durchschnitts Tabellen in viele-zu-viele Beziehungen, oder
- die meisten Tabellen mit komponierten Primärschlüsseln.
- </para>
- </note>
- </sect3>
- </sect2>
- <sect2 id="zend.db.table.update">
- <title>Zeilen in einer Tabelle aktualisieren</title>
- <para>
- Spalten können in der Datenbanktabelle aktualisiert werden indem die <code>update</code>
- Methode der Table Klasse verwendet wird. Diese Methode nimmt zwei Argumente: ein
- assoziatives Array von Spalten die geändert werden sollen und neue Werte die diesen
- Spalten hinzugefügt werden; und einen SQL Ausdruck der in der <code>WHERE</code> Klausel
- verwendet wird, als Kriterium für die Zeilen die in der <code>UPDATE</code> Operation
- geändert werden sollen.
- </para>
- <example id="zend.db.table.update.example">
- <title>Beispiel für das Aktualisieren von Zeilen in einer Tabelle</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $data = array(
- 'updated_on' => '2007-03-23',
- 'bug_status' => 'FIXED'
- );
- $where = $table->getAdapter()->quoteInto('bug_id = ?', 1234);
- $table->update($data, $where);
- ]]></programlisting>
- </example>
- <para>
- Da die <code>update()</code> Methode der Tabelle zur
- <link linkend="zend.db.adapter.write.update"><code>update()</code></link> Methode des
- Datenbank Adapters weiterleitet, kann das zweite Argument ein Array von SQL Ausdrücken
- sein. Diese Ausdrücke werden als Boolsche Terme kombiniert indem ein <code>AND</code>
- Operator verwendet wird.
- </para>
- <note>
- <para>
- Die Werte und Identifizierer im SQL Ausdruck werden nicht in Anführungszeichen
- gesetzt. Wenn Werte oder Identifizierer vorhanden sind die das Setzen in
- Anführungszeichen benötigen, ist man selbst dafür zuständig das das getan wird. Die
- <code>quote()</code>, <code>quoteInto()</code> und <code>quoteIdentifier()</code>
- Methoden des Datenbank Adapters können dafür verwendet werden.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.db.table.delete">
- <title>Zeilen aus einer Tabelle löschen</title>
- <para>
- Zeilen können von einer Datenbanktabelle gelöscht werden indem die <code>delete()</code>
- Methode verwendet wird. Diese Methode nimmt ein Argument, welches ein SQL Ausdruck ist,
- der in der <code>WHERE</code> Klausel als Kriterium dafür verwendet wird, welche Zeilen
- gelöscht werden sollen.
- </para>
- <example id="zend.db.table.delete.example">
- <title>Beispiel für das Löschen von Zeilen einer Tabelle</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $where = $table->getAdapter()->quoteInto('bug_id = ?', 1235);
- $table->delete($where);
- ]]></programlisting>
- </example>
- <para>
- Da die <code>delete()</code> Methode der Tabelle zur
- <link linkend="zend.db.adapter.write.delete"><code>delete()</code></link> Methode des
- Datenbank Adapters weiterleitet, kann das Argument ein Array von SQL Ausdrücken sein.
- Diese Ausdrücke werden als boolsche Terme kombiniert indem ein <code>AND</code> Operator
- verwendet wird.
- </para>
- <note>
- <para>
- Die Werte und Identifizierer im SQL Ausdruck werden nicht in Anführungszeichen
- gesetzt. Wenn Werte oder Identifizierer vorhanden sind die das Setzen in
- Anführungszeichen benötigen, ist man selbst dafür zuständig das das getan wird. Die
- <code>quote()</code>, <code>quoteInto()</code> und <code>quoteIdentifier()</code>
- Methoden des Datenbank Adapters können dafür verwendet werden.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.db.table.find">
- <title>Zeilen durch den Primärschlüssel finden</title>
- <para>
- Die Datenbanktabelle kann nach passenden Zeilen für spezifizierte Werte im
- Primärschlüssel abgefragt werden, indem die <code>find()</code> Methode verwendet wird.
- Das erste Argument dieser Methode ist entweder ein einzelner Wert oder ein Array von
- Werten die dem Primärschlüssel dieser Tabelle entsprechen.
- </para>
- <example id="zend.db.table.find.example">
- <title>Beispiel für das Finden von Zeilen durch Werte des Primärschlüssels</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- // Eine einzelne Zeile finden
- // Gibt ein Rowset zurück
- $rows = $table->find(1234);
- // Mehrere Zeilen finden
- // Gibt auch ein Rowset zurück
- $rows = $table->find(array(1234, 5678));
- ]]></programlisting>
- </example>
- <para>
- Wenn ein einzelner Wert spezifiziert wird, gibt die Methode auch maximal eine Zeile
- zurück, weil ein Primärschlüssel keinen doppelten Wert haben kann und es maximal eine
- Zeile in der Datenbank gibt die dem spezifizierten Wert entspricht. Wenn mehrere Werte
- in einem Array spezifiziert werden, gibt die Methode maximal soviele Zeilen zurück wie
- die Anzahl an unterschiedlichen Werten die spezifiziert wurden.
- </para>
- <para>
- Die <code>find()</code> Methode kann weniger Zeilen zurückgeben als die Anzahl an Werten
- die für den Primärschlüssel definiert wurden, wenn einige der Werte keiner Zeile in der
- Datenbank Tabelle entsprechen. Die Methode kann sogar null Zeilen zurückgeben. Weil die
- Anzahl an zurückgegebenen Zeilen variabel ist, gibt die <code>find()</code> Methode ein
- Objekt vom Typ <classname>Zend_Db_Table_Rowset_Abstract</classname> zurück.
- </para>
- <para>
- Wenn der Primärschlüssel ein komponierter Schlüssel ist, als einer der aus mehreren
- Spalten besteht, können die zusätzlichen Spalten als zusätzliche Argumente in der
- <code>find()</code> Methode definiert werden. Es müssen soviele Argumente angegeben
- werden wie Spalten im Primärschlüssel der Tabelle existieren.
- </para>
- <para>
- Um mehrere Zeilen von einer Tabelle mit einem kombinierten Primärschlüssel zu finden,
- muß ein Array für jedes der Argumente übergeben werden. Alle dieser Arrays müssen die
- gleiche Anzahl an Elementen haben. Die Werte in jedem Array werden in Tupeln geformt und
- gereiht; zum Beispiel definiert das erste Element in allen Array Argumenten den ersten
- kombinierten Wert des Primärschlüssels, das zweite Element von allen Arrays definiert
- den zweiten kombinierten Wert des Primärschlüssels, und so weiter.
- </para>
- <example id="zend.db.table.find.example-compound">
- <title>
- Beispiel für das Finden von Zeilen durch Werte von kombinierten Primärschlüsseln
- </title>
- <para>
- Der Aufruf von <code>find()</code> anbei um mehreren Zeilen zu entsprechen kann zwei
- Zeilen in der Datenbank entsprechen. Die erste Zeile muß den Wert des
- Primärenschlüssels (1234, 'ABC') haben, und die zweite Zeile den Wert des
- Primärschlüssels (5678, 'DEF').
- </para>
- <programlisting language="php"><![CDATA[
- class BugsProducts extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs_products';
- protected $_primary = array('bug_id', 'product_id');
- }
- $table = new BugsProducts();
- // Eine einzelne Zeilen mit einem kombinierten Primärschlüssel finden
- // Gibt ein Rowset zurück
- $rows = $table->find(1234, 'ABC');
- // Mehrere Zeilen mit einem kombinierten Primärschlüssel finden
- // Gibt auch ein Rowset zurück
- $rows = $table->find(array(1234, 5678), array('ABC', 'DEF'));
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.db.table.fetch-all">
- <title>Ein Set von Zeilen abfragen</title>
- <sect3 id="zend.db.table.fetch-all.select">
- <title>Select API</title>
- <para>
- <warning>
- <para>
- Die API für die Hol-Operationen wurde ausgeweitet um einem
- <classname>Zend_Db_Table_Select</classname> Objekt zu erlauben die Abfrage
- zu modifizieren. Trotzdem wird die veraltete Verwendung der
- <code>fetchRow()</code> und <code>fetchAll()</code> Methoden weiterhin ohne
- Änderungen funktionieren.
- </para>
- <para>
- Die folgenden Ausdrücke sind gültig und funktionell identisch, trotzdem wird
- empfohlen den Code zu aktualisieren um Vorteil aus der neuen Verwendung zu
- ziehen wo das möglich ist.
- </para>
- <para>
- <programlisting language="php"><![CDATA[
- // Ein Rowset holen
- $rows = $table->fetchAll('bug_status = "NEW"', 'bug_id ASC', 10, 0);
- $rows = $table->fetchAll($table->select()->where('bug_status = ?', 'NEW')
- ->order('bug_id ASC')
- ->limit(10, 0));
- // Eine einzelne Zeile holen
- $row = $table->fetchRow('bug_status = "NEW"', 'bug_id ASC');
- $row = $table->fetchRow($table->select()->where('bug_status = ?', 'NEW')
- ->order('bug_id ASC'));
- ]]></programlisting>
- </para>
- </warning>
- </para>
- <para>
- Das <classname>Zend_Db_Table_Select</classname> Objekt ist eine Erweiterung des
- <classname>Zend_Db_Select</classname> Objekts das spezielle Einschränkungen zu einer
- Abfrage hinzufügt. Die Verbesserungen und Einschränkungen sind folgende:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- Man <emphasis>kann</emphasis> sich entscheiden ein Subset von Zeilen einer
- fetchRow oder fetchAll Abfrage zurückzuerhalten. Dann kann Vorteile durch
- Optimierung bieten, wenn die Rückgabe eines großes Sets an Ergebnissen für
- alle Zeilen nicht gewünscht wird.
- </para>
- </listitem>
- <listitem>
- <para>
- Man <emphasis>kann</emphasis> Zeilen spezifizieren die Ausdrücke innerhalb
- der ausgewählten Tabelle evaluieren. Trotzdem bedeutet das, das die
- zurückgegebene Zeile oder Zeilenset <property>readOnly</property> (nur
- lesbar) ist und nicht für save() Operationen verwendet werden kann. Eine
- <classname>Zend_Db_Table_Row</classname> mit <property>readOnly</property>
- Status wird eine Exception werfen wenn eine <code>save()</code> Operation
- versucht wird.
- </para>
- </listitem>
- <listitem>
- <para>
- Man <emphasis>kann</emphasis> JOIN Klauseln auf einer Auswahl erlauben um
- Mehrfach-Tabellen Lookups zu erlauben.
- </para>
- </listitem>
- <listitem>
- <para>
- Man <emphasis>kann keine</emphasis> Spalten von einer geJOINten Tabelle
- spezifizieren damit Sie in einer Zeile/Zeilenset zurückgegeben werden. Wenn
- das versucht wird, wird ein PHP Fehler getriggert. Das wurde getan um
- Sicherzustellen das die Integrität von <classname>Zend_Db_Table gewahrt
- bleibt</classname>. z.B. ein <classname>Zend_Db_Table_Row</classname> sollte
- nur Spalten referenzieren die von seiner Elterntabelle abgeleitet sind.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- <example id="zend.db.table.qry.rows.set.simple.usage.example">
- <title>Einfache Verwendung</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $select = $table->select();
- $select->where('bug_status = ?', 'NEW');
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- </para>
- <para>
- Flüssige Interfaces sind über alle Komponenten hinweg implementiert, sodas das zu
- einer mehr abgekürzteren Form umgeschrieben werden kann.
- </para>
- <para>
- <example id="zend.db.table.qry.rows.set.fluent.interface.example">
- <title>Example of fluent interface</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $rows =
- $table->fetchAll($table->select()->where('bug_status = ?', 'NEW'));
- ]]></programlisting>
- </example>
- </para>
- </sect3>
- <sect3 id="zend.db.table.fetch-all.usage">
- <title>Ein Set von Zeilen abfragen</title>
- <para>
- Ein Set von Zeilen kann abgefragt werden indem irgendein Kriterium verwendet wird,
- das anders als die Werte des Primärschlüssels sind, indem die
- <code>fetchAll()</code> Methode der Tabellen Klasse verwendet wird. Diese Methode
- gibt ein Objekt vom Typ <classname>Zend_Db_Table_Rowset_Abstract</classname> zurück.
- </para>
- <example id="zend.db.table.qry.rows.set.finding.row.example">
- <title>Beispiel für das Finden von Zeilen durch einen Ausdruck</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $select = $table->select()->where('bug_status = ?', 'NEW');
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- <para>
- Der <code>ORDER BY</code> kann auch ein Sortier-Kriterium übergeben werden, genauso
- wie auch Count und Offset Integer Werte, verwendet werden können damit die Abfrage
- ein spezielles Subset von Zeilen zurück gibt. Diese Werte werden in einer
- <code>LIMIT</code> Klausel verwendet oder in einer ähnlichen Logik für RDBMS Marken
- die die <code>LIMIT</code> Syntax nicht unterstützen.
- </para>
- <example id="zend.db.table.fetch-all.example2">
- <title>Beispiel für das Finden von Zeilen durch einen Ausdruck</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $order = 'bug_id';
- // Gibt die Zeilen 21 bis 30 zurück
- $count = 10;
- $offset = 20;
- $select = $table->select()->where(array('bug_status = ?' => 'NEW'))
- ->order($order)
- ->limit($count, $offset);
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- <para>
- Alle diese Argumente sind optional. Wenn die ORDER Klausel unterdrückt wird, dann
- enthält das Ergebnis die Zeilen der Tabelle in einer unvorhersagbaren Reihenfolge.
- Wenn keine LIMIT Klausel gesetzt ist, dann wird jede Zeile dieser Tabelle
- zurückgegeben die der WHERE Klausen entspricht.
- </para>
- </sect3>
- <sect3 id="zend.db.table.advanced.usage">
- <title>Fortgeschrittene Verwendung</title>
- <para>
- Für speziellere und optimierte Ergebnisse, kann es gewünscht sein die Anzahl der
- zurückgegebenen Zeilen/Sets zu limitieren. Das kann durch die Übergabe einer FROM
- Klausel an das Select Objekt getan werden. Das erste Argument in der FROM Klausel
- ist identisch mit den des <classname>Zend_Db_Select</classname> Objekts wobei man
- zusätzlich eine Instanz von <classname>Zend_Db_Table_Abstract</classname> übergeben
- und damit den Tabellen Namen automatisch ermitteln lassen kann.
- </para>
- <para>
- <example id="zend.db.table.qry.rows.set.retrieving.a.example">
- <title>Spezielle Spalten erhalten</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $select = $table->select();
- $select->from($table, array('bug_id', 'bug_description'))
- ->where('bug_status = ?', 'NEW');
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- </para>
- <para>
- <important>
- <para>
- Das Rowset enthält Zeilen die trotzdem 'gültig' sind - sie enthalten bloß
- ein Subset der Spalten einer Tabelle. Wenn eine save() Methode auf dem Teil
- einer Zeile aufgerufen wird dann werden nur die vorhandenen Felder geändert.
- aufgerufen
- </para>
- </important>
- Es können Ausdrücke in einer FROM Klausel spezifiziert werden die dann als readOnly
- Zeile/Set zurückgegeben werden. In diesem Beispiel werden Zeilen von der Bugs
- Tabelle zurückgegeben die einen Bereich von Nummern neuer Bugs zeigen die von
- Individuen mitgeteilt wurden. Die GROUP Klausel ist zu beachten. Die 'count' Spalte
- wird der Zeile für Evaluation angefügt und es kann auch Sie zugegriffen werden wie
- wenn Sie ein Teil des Schemas wäre.
- </para>
- <para>
- <example id="zend.db.table.qry.rows.set.retrieving.b.example">
- <title>Ausdrücke als Spalten erhalten</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $select = $table->select();
- $select->from($table,
- array('COUNT(reported_by) as `count`', 'reported_by'))
- ->where('bug_status = ?', 'NEW')
- ->group('reported_by');
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- Es kann auch ein Lookup als Teil der Abfrage verwendet werden um die Fetch
- Operation zu verfeinern. In diesem Beispiel wird die Accounts Tabelle als Teil
- einer Suche nach allen Bugs die von 'Bob' gemeldet wurden, abgefragt.
- </para>
- <para>
- <example id="zend.db.table.qry.rows.set.refine.example">
- <title>Beispiel für das Finden von Zeilen durch einen Ausdruck</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- // Bei gesetztem From Abschnitt empfangen, wichtig wenn gejoint werden soll
- $select = $table->select(Zend_Db_Table::SELECT_WITH_FROM_PART);
- $select->setIntegrityCheck(false)
- ->where('bug_status = ?', 'NEW')
- ->join('accounts', 'accounts.account_name = bugs.reported_by')
- ->where('accounts.account_name = ?', 'Bob');
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- </para>
- <para>
- <classname>Zend_Db_Table_Select</classname> wird primär verwendet um zu verbinden
- und zu prüfen um die Kriterien für einen legalen SELECT Query sicherzustellen.
- Trotzdem gibt es viele Fälle in denen man die Flexibilität der
- <classname>Zend_Db_Table_Row</classname> benötigt und Zeilen nicht geschrieben oder
- gelöscht werden müssen. Für diesen speziellen Fall ist es möglich Zeilen/-sets durch
- die Übergabe eines false Wertes an setIntegrityCheck zu erhalten. Das resultierende
- Zeilen/-set wird als eine 'locked' Zeile zurückgegeben (das bedeutet das save(),
- delete() und jede andere Mothode die Felder setzt wird eine Ausnahme werfen).
- </para>
- <example id="zend.db.table.qry.rows.set.integrity.example">
- <title>
- Entfernen des Integritäts Checks von Zend_Db_Table_Select um geJOINte Zeilen zu
- erlauben
- </title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $select = $table->select(Zend_Db_Table::SELECT_WITH_FROM_PART)->setIntegrityCheck(false);
- $select->where('bug_status = ?', 'NEW')
- ->join('accounts',
- 'accounts.account_name= bugs.reported_by',
- 'account_name')
- ->where('accounts.account_name = ?', 'Bob');
- $rows = $table->fetchAll($select);
- ]]></programlisting>
- </example>
- </sect3>
- </sect2>
- <sect2 id="zend.db.table.fetch-row">
- <title>Eine einzelne Zeilen abfragen</title>
- <para>
- Eine einzelne Zeile kann abgefragt werden indem Kriterien verwendet werden die ähnlich
- denen der <code>fetchAll()</code> Methode sind.
- </para>
- <example id="zend.db.table.fetch-row.example1">
- <title>Beispiel für das Finden einer einzelnen Zeilen durch einen Ausdruck</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $select = $table->select()->where('bug_status = ?', 'NEW')
- ->order('bug_id');
- $row = $table->fetchRow($select);
- ]]></programlisting>
- </example>
- <para>
- Diese Methode gibt ein Objekt vom Typ <classname>Zend_Db_Table_Row_Abstract</classname>
- zurück. Wenn die spezifizierten Sortier-Kriterien keiner Zeile in der Datenbank Tabelle
- entsprechen gibt <code>fetchRow()</code> PHP's <constant>NULL</constant> Wert zurück.
- </para>
- </sect2>
- <sect2 id="zend.db.table.info">
- <title>Informationen der Tabellen Metadaten erhalten</title>
- <para>
- Die <classname>Zend_Db_Table_Abstract</classname> Klasse bietet einige Informationen
- über Ihre Metadaten. Die <code>info()</code> Methode gibt eine Array Struktur mit
- Informationen über die Tabelle, Ihre Spalten und Primärschlüssel zurück, sowie andere
- Metadaten.
- </para>
- <example id="zend.db.table.info.example">
- <title>Beispiel für das Erhalten des Namens einer Tabelle</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $info = $table->info();
- echo "Der Name der Tabelle ist " . $info['name'] . "\n";
- ]]></programlisting>
- </example>
- <para>
- Die Schlüssel des Arrays das von der <code>info()</code> Methode zurückgegeben wird sind
- anbei beschrieben:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>name</emphasis> => der Name der Tabelle.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>cols</emphasis> => ein Array das die Spalte(n) der Tabelle benennt.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>primary</emphasis> => ein Array das die Spalte(n) des Primärschlüssels
- benennt.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>metadata</emphasis> => ein assoziatives Array das die Spaltennamen
- mit Informationen über die Spalten zusammenführt. Das ist die Information die
- durch die <code>describeTable()</code> Methode zurückgegeben wird.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>rowClass</emphasis> => der Name der konkreten Klasse die für
- Zeilen Objekte verwendet wird und von den Methoden dieser Table Instanz
- zurückgegeben wird. Der Standardwert ist
- <classname>Zend_Db_Table_Row</classname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>rowsetClass</emphasis> => Name der konkreten Klasse für für Rowset
- Objekte verwendet wird und von den Methoden dieser Table Instanz zurückgegeben
- wird. Der Standardwert ist <classname>Zend_Db_Table_Rowset</classname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>referenceMap</emphasis> => ist ein assoziatives Array von
- Klassennamen von Tabellen die diese Tabelle referenzieren. Siese
- <xref linkend="zend.db.table.relationships.defining" />.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>dependentTables</emphasis> => ein Array von Klassennamen von
- Tabellen die diese Tabelle referenzieren. Siese
- <xref linkend="zend.db.table.relationships.defining" />.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>schema</emphasis> => der Name des Schemas (oder der
- Datenbank oder dem Tabellenraum) für diese Tabelle.
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- <sect2 id="zend.db.table.metadata.caching">
- <title>Tabellen Metadaten cachen</title>
- <para>
- Standardmäßig fragt <classname>Zend_Db_Table_Abstract</classname> die darunterliegende
- Datenbank für die <link linkend="zend.db.table.info">Metadaten der Tabelle</link> ab
- immer wenn diese diese Daten benötigt werden um Tabellenoperationen durchzuführen. Das
- Tableobjekt holt die Metadaten der Tabelle von der Datenbank indem es die
- <code>describeTable()</code> Methode des Adapters verwendet. Operationen die diese
- Einsicht benötigten sind:
- </para>
- <itemizedlist>
- <listitem><para><code>insert()</code></para></listitem>
- <listitem><para><code>find()</code></para></listitem>
- <listitem><para><code>info()</code></para></listitem>
- </itemizedlist>
- <para>
- In einigen Fällen, speziell wenn viele Table Objekte auf der gleichen Datenbanktabelle
- instanziert werden kann das Abfragen der Datenbank nach den Metadaten der Tabelle für
- jede Instanz unerwünscht sein wegen der Geschwindigkeit. In solchen Fällen, können
- Benutzer davon profitieren das die Metadaten der Tabelle, die von der Datenbank
- empfangen werden, gecached werden.
- </para>
- <para>
- Es gibt zwei grundsätzliche Wege bei denen ein Benutzer Vorteile davon haben kann wenn
- die Metadaten der Tabelle gecached werden:
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>Aufruf von
- <classname>Zend_Db_Table_Abstract::setDefaultMetadataCache()</classname></emphasis>
- - Das erlaubt es Entwicklern das Standardcacheobjekt zu setzen das für alle
- Tabellenklassen verwendet werden soll.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>Konfigurieren von
- <classname>Zend_Db_Table_Abstract::__construct()</classname></emphasis> -
- Das erlaubt es Entwicklern das Cacheobjekt zu setzen das für eine spezielle
- Instanz der Tabellenklasse verwendet werden soll.
- </para>
- </listitem>
- </itemizedlist>
- In beiden Fällen muß die Spezifikation des Caches entweder <constant>NULL</constant> (wenn kein
- Cache verwendet wird) oder eine Instanz von
- <link linkend="zend.cache.frontends.core"><classname>Zend_Cache_Core</classname></link>
- sein. Die Methoden können in Verbindung zueinander verwendet werden wenn es gewünscht
- ist beides zu haben, einen standardmäßigen Cache für die Metadaten und die Möglichkeit
- den Cache eines individuellen Tabellenobjektes zu ändern.
- </para>
- <example id="zend.db.table.metadata.caching-default">
- <title>
- Verwenden eines standardmäßigen Caches für Metadaten für alle Tabellenobjekte
- </title>
- <para>
- Der folgende Code demonstriert wie ein standardmäßiger Cache für die Metadaten
- gesetzt werden kann der für alle Tabellenobjekte verwendet wird:
- </para>
- <programlisting language="php"><![CDATA[
- // Zuerst muß der Cache vorbereitet werden
- $frontendOptions = array(
- 'automatic_serialization' => true
- );
- $backendOptions = array(
- 'cache_dir' => 'cacheDir'
- );
- $cache = Zend_Cache::factory('Core',
- 'File',
- $frontendOptions,
- $backendOptions);
- // Als nächstes, den Cache setzen der mit allen Tabellenobjekten verwendet werden soll
- Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
- // Eine Tabellenklasse wird auch benötigt
- class Bugs extends Zend_Db_Table_Abstract
- {
- // ...
- }
- // Jede Instanz von Bugs verwenden nur den Standardmäßigen Cache fpr die Metadaten
- $bugs = new Bugs();
- ]]></programlisting>
- </example>
- <example id="zend.db.table.metadata.caching-instance">
- <title>Einen Metadaten Cache für ein spezielles Tabellenobjekt verwenden</title>
- <para>
- Der folgende Code demonstriert wie ein Cache für Metadaten für eine spezielle
- Instanz eines Tabellenobjektes gesetzt werden kann:
- </para>
- <programlisting language="php"><![CDATA[
- // Zuerst den Cache vorbereiten
- $frontendOptions = array(
- 'automatic_serialization' => true
- );
- $backendOptions = array(
- 'cache_dir' => 'cacheDir'
- );
- $cache = Zend_Cache::factory('Core',
- 'File',
- $frontendOptions,
- $backendOptions);
- // Eine Tabellenklasse wird auch benötigt
- class Bugs extends Zend_Db_Table_Abstract
- {
- // ...
- }
- // Eine Instanz für die Instanzierung konfgurieren
- $bugs = new Bugs(array('metadataCache' => $cache));
- ]]></programlisting>
- </example>
- <note>
- <title>Automatische Serialisierung mit dem Cache Frontend</title>
- <para>
- Da die Information die von der describeTable() Methode des Adapters zurückgegeben
- wird, ein Array ist, muß sichergestellt werden das die
- <code>automatic_serialization</code> Option für das
- <classname>Zend_Cache_Core</classname> Frontend auf <constant>TRUE</constant> gesetzt wird.
- </para>
- </note>
- <para>
- Obwohl die obigen Beispiele <classname>Zend_Cache_Backend_File</classname> verwenden,
- können Entwickler jegliches Cache Backend verwenden das der Situation am besten
- entspricht. Siehe <link linkend="zend.cache">Zend_Cache</link> für weitere
- Informationen.
- </para>
- <sect3 id="zend.db.table.metadata.caching.hardcoding">
- <title>Tabellen Metadaten hardcoden</title>
- <para>
- Um das Cachen von Metadaten einen weiteren Schritt weiterzubringen, kann man sich
- auch entscheiden die Metadaten hardzucoden. In diesem speziellen Fall benötigt jede
- Änderung trotzdem eine Änderung im Code. Als solches, ist es nur empfohlen für jene
- die eine Produktionsumgebung optimieren wollen.
- </para>
- <para>
- Die Struktur der Metadaten ist wie folgt:
- </para>
- <programlisting language="php"><![CDATA[
- protected $_metadata = array(
- '<column_name>' => array(
- 'SCHEMA_NAME' => <string>,
- 'TABLE_NAME' => <string>,
- 'COLUMN_NAME' => <string>,
- 'COLUMN_POSITION' => <int>,
- 'DATA_TYPE' => <string>,
- 'DEFAULT' => NULL|<value>,
- 'NULLABLE' => <bool>,
- 'LENGTH' => <string - length>,
- 'SCALE' => NULL|<value>,
- 'PRECISION' => NULL|<value>,
- 'UNSIGNED' => NULL|<bool>,
- 'PRIMARY' => <bool>,
- 'PRIMARY_POSITION' => <int>,
- 'IDENTITY' => <bool>,
- ),
- // additional columns...
- );
- ]]></programlisting>
- <para>
- Ein einfacher Weg um die richtigen Werte zu erhalten ist es den Metadaten Cache zu
- verwenden, und dann die Werte die im Cache gespeichert sind, zu deserialisieren.
- </para>
- <para>
- Diese Optimierung kann ausgeschaltet werden indem das
- <code>metadataCacheInClass</code> Flag ausgeschaltet wird:
- </para>
- <programlisting language="php"><![CDATA[
- // Bei der Instanziierung:
- $bugs = new Bugs(array('metadataCacheInClass' => false));
- // Oder später:
- $bugs->setMetadataCacheInClass(false);
- ]]></programlisting>
- <para>
- Das Flag ist standardmäßig aktiviert, was sicherstellt das das
- <varname>$_metadata</varname> Array nur einmal pro Instanz ausgeliefert wird.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.db.table.extending">
- <title>Eine Table Klasse erweitern und anpassen</title>
- <sect3 id="zend.db.table.extending.row-rowset">
- <title>Verwenden eigener Zeilen oder Rowset Klassen</title>
- <para>
- Standardmäßig geben die Methoden der Table Klasse ein Rowset als Instanzen der
- konkreten Klasse <classname>Zend_Db_Table_Rowset</classname>, und Rowsets enthalten
- eine Kollektion von Instanzen der konkreten Klasse
- <classname>Zend_Db_Table_Row</classname>. Eine alternative Klasse kann für jede von
- Ihnen als alternative Klasse definiert werden die verwendet werden soll, aber es
- müssen Klassen sein die <classname>Zend_Db_Table_Rowset_Abstract</classname>
- erweitern und respektiv <classname>Zend_Db_Table_Row_Abstract</classname>.
- </para>
- <para>
- Es können Zeilen und Rowset Klassen definiert werden indem das Optionsarray des
- Table Konstruktors verwendet wird, respektiv die Schlüssel <code>'rowClass'</code>
- und <code>'rowsetClass'</code>. Die Namen der Klassen müssen spezifiziert werden
- indem Strings verwendet werden.
- </para>
- <example id="zend.db.table.extending.row-rowset.example">
- <title>
- Beispiel dafür wie die Zeilen und Rowset Klassen spezifiziert werden können
- </title>
- <programlisting language="php"><![CDATA[
- class My_Row extends Zend_Db_Table_Row_Abstract
- {
- ...
- }
- class My_Rowset extends Zend_Db_Table_Rowset_Abstract
- {
- ...
- }
- $table = new Bugs(
- array(
- 'rowClass' => 'My_Row',
- 'rowsetClass' => 'My_Rowset'
- )
- );
- $where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
- // Gibt ein Objekt des Typs My_Rowset zurück
- // das ein Array von Objekten des Typs My_Row enthält.
- $rows = $table->fetchAll($where);
- ]]></programlisting>
- </example>
- <para>
- Die Klassen können geändert werden indem Sie mit den <code>setRowClass()</code> und
- <code>setRowsetClass()</code> Methoden spezifiziert werden. Das entspricht den
- Zeilen und Rowsets die nachfolgend erstellt werden; es ändert aber nicht die Klasse
- von Zeilen- oder Rowsetobjekten die bereits davor erstellt wurden.
- </para>
- <example id="zend.db.table.extending.row-rowset.example2">
- <title>Beispiel für das Ändern von Zeilen und Rowset Klassen</title>
- <programlisting language="php"><![CDATA[
- $table = new Bugs();
- $where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
- // Gibt ein Objekt vom Typ Zend_Db_Table_Rowset zurück das ein Array
- // von Objekten des Typs Zend_Db_Table_Row enthält.
- $rowsStandard = $table->fetchAll($where);
- $table->setRowClass('My_Row');
- $table->setRowsetClass('My_Rowset');
- // Gibt ein Objekt vom Typ My_Rowset zurück das ein Array
- // von Objekten des Typs My_Row enthält.
- $rowsCustom = $table->fetchAll($where);
- // Das $rowsStandard Objekt existiert noch immer, und es bleibt unverändert.
- ]]></programlisting>
- </example>
- <para>
- Für weitere Informationen über Zeilen und Rowset Klassenm siehe
- <xref linkend="zend.db.table.row" /> und <xref linkend="zend.db.table.rowset" />.
- </para>
- </sect3>
- <sect3 id="zend.db.table.extending.insert-update">
- <title>Selbst definierte Logik für das Einfügen, Aktualisieren und Löschen</title>
- <para>
- Die <code>insert()</code> und <code>update()</code> Methoden in der Table Klasse
- können überschrieben werden. Das bietet die Möglichkeit eigenen Code einzufügen der
- ausgeführt wird bevor die Datenbank Operation durchgeführt wird. Es muß
- sichergestellt werden das die Methode der Elternklasse aufgerufen wird wenn man
- fertig ist.
- </para>
- <example id="zend.db.table.extending.insert-update.example">
- <title>Eigene Logik um Zeitstempel zu managen</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- public function insert(array $data)
- {
- // Einen Zeitstempel hinzufügen
- if (empty($data['created_on'])) {
- $data['created_on'] = time();
- }
- return parent::insert($data);
- }
- public function update(array $data, $where)
- {
- // Einen Zeitstempel hinzufügen
- if (empty($data['updated_on'])) {
- $data['updated_on'] = time();
- }
- return parent::update($data, $where);
- }
- }
- ]]></programlisting>
- </example>
- <para>
- Auch die <code>delete()</code> Methode kann überschrieben werden.
- </para>
- </sect3>
- <sect3 id="zend.db.table.extending.finders">
- <title>Eigene Such Methoden in Zend_Db_Table definieren</title>
- <para>
- Es können eigene Abfrage Methoden in der Table Klasse implementiert werden, wenn oft
- die Notwendigkeit besteht Abragen mit speziellen Kriterien auf der Table Klasse
- durchzuführen. Die meisten Abfragen können mit <code>fetchAll()</code> geschrieben
- werden, das bedeutet aber das Code dupliziert werden muß um Abfragekonditionen zu
- formen die Abfrage in verschiedenen Orten der Anwendung auszuführen. Hierfür kann es
- nützlich sein eine Methode in der Table Klasse zu definieren um oft benutzte
- Abfragen an dieser Tabelle durchzuführen.
- </para>
- <example id="zend.db.table.extending.finders.example">
- <title>Eigene Methode um Fehler durch den Status zu finden</title>
- <programlisting language="php"><![CDATA[
- class Bugs extends Zend_Db_Table_Abstract
- {
- protected $_name = 'bugs';
- public function findByStatus($status)
- {
- $where = $this->getAdapter()->quoteInto('bug_status = ?', $status);
- return $this->fetchAll($where, 'bug_id');
- }
- }
- ]]></programlisting>
- </example>
- </sect3>
- <sect3 id="zend.db.table.extending.inflection">
- <title>Inflection (Beugung) in Zend_Db_Table definieren</title>
- <para>
- Einige Leute bevorzugen das der Name der Table Klasse einem Tabellennamen in der
- RDBMS, durch eine Stringumwandlung die <emphasis>Inflection</emphasis> (Beugung)
- genannt wird, entspricht.
- </para>
- <para>
- Wenn zum Beispiel der Name der Table Klasse "<code>BugsProducts</code>" ist, würde
- Sie der physikalischen Tabelle in der Datenbank entsprechen die
- "<code>bugs_products</code>" heißt, wenn die explizite Definition der
- <varname>$_name</varname> Eigenschaft der Klasse unterdrückt wird. In dieser
- Übereinstimmung der Beugung, wird der Klassenname im "CamelCase" Format geschrieben
- und in Kleinschreibung transformiert, und Wörter mit einem Unterstrich seperiert.
- </para>
- <para>
- Der Tabellenname der Datenbank kann unabhängig vom Klassennamen spezifiziert werden
- indem der Tabellenname mit der Klasseneigenschaft <varname>$_name</varname> in jeder der
- eigenen Tabellenklassen deklariert wird.
- </para>
- <para>
- <classname>Zend_Db_Table_Abstract</classname> führt keine Beugung durch um die
- Klassennamen mit den Tabellennamen in Übereinstimmung zu bringen. Wenn die
- Deklaration von <varname>$_name</varname> in der eigenen Tabellenklasse unterdrückt wird,
- wird die Klasse mit der Datenbanktabelle in Verbindung gebracht die der Schreibweise
- des Klassennamens exakt entspricht.
- </para>
- <para>
- Es ist unzureichend Identifizierer von der Datenbank zu transformieren, da das zu
- Doppeldeutigkeiten führen kann oder einige Identifizierer sogar unerreichbar macht.
- Die Verwendung der SQL Identifizierer exakt so wie Sie in der Datenbank vorhanden
- sind, macht <classname>Zend_Db_Table_Abstract</classname> sowohl einfacher als auch
- flexibler.
- </para>
- <para>
- Wenn man es vorzieht Beugung zu verwenden, muß die Transformation selbst durch das
- Überschreiben der <code>_setupTableName()</code> Methode in der eigenen
- Tabellenklasse implementiert werden. Ein Weg um das zu tun ist die Definition einer
- abstrakten Klase die <classname>Zend_Db_Table_Abstract</classname> erweitert. Der
- Rest der eigenen Klassen erweitert dann die eigene neue abstrakte Klasse.
- </para>
- <example id="zend.db.table.extending.inflection.example">
- <title>Beispiel einer abstrakten Tabellenklasse die Beugung implementiert</title>
- <programlisting language="php"><![CDATA[
- abstract class MyAbstractTable extends Zend_Db_Table_Abstract
- {
- protected function _setupTableName()
- {
- if (!$this->_name) {
- $this->_name = myCustomInflector(get_class($this));
- }
- parent::_setupTableName();
- }
- }
- class BugsProducts extends MyAbstractTable
- {
- }
- ]]></programlisting>
- </example>
- <para>
- Man ist selbst für das Schreiben von Funktionen verantwortlich um die Transformation
- der Beugung auszuführen. Zend Framework bietet solche Funktionen nicht an.
- </para>
- </sect3>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|