[GENERIC] Zend_Translate:
[zend.git] / documentation / manual / ja / module_specs / Zend_Db_Table_Row.xml
bloba2d3f50b8842e2845afee7e17b1315e43acbf04f
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <!-- EN-Revision: 20766 -->
4 <sect1 id="zend.db.table.row">
6     <title>Zend_Db_Table_Row</title>
8     <sect2 id="zend.db.table.row.introduction">
10         <title>導入</title>
12         <para>
13             <classname>Zend_Db_Table_Row</classname> は、<classname>Zend_Db_Table</classname> オブジェクトの個々の行を含むクラスです。
14             テーブルクラスに対してクエリを実行すると、返される結果は
15             <classname>Zend_Db_Table_Row</classname> オブジェクトのセットとなります。
16             このオブジェクトを使用して新しい行を作成し、
17             それをデータベースのテーブルに追加することもできます。
18         </para>
20         <para>
21             <classname>Zend_Db_Table_Row</classname> は、
22             <ulink url="http://www.martinfowler.com/eaaCatalog/rowDataGateway.html">
23             行データゲートウェイ</ulink>パターンを実装したものです。
24         </para>
26     </sect2>
28     <sect2 id="zend.db.table.row.read">
30         <title>行の取得</title>
32         <para>
33             <classname>Zend_Db_Table_Abstract</classname> は <methodname>find()</methodname> や
34             <methodname>fetchAll()</methodname> といったメソッドを提供します。
35             これらはそれぞれ <classname>Zend_Db_Table_Rowset</classname> 型のオブジェクトを返します。
36             また <methodname>fetchRow()</methodname> メソッドは、
37             <classname>Zend_Db_Table_Row</classname> 型のオブジェクトを返します。
38         </para>
40         <example id="zend.db.table.row.read.example">
42             <title>行の取得の例</title>
44             <programlisting language="php"><![CDATA[
45 $bugs = new Bugs();
46 $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
47 ]]></programlisting>
49         </example>
51         <para>
52             <classname>Zend_Db_Table_Rowset</classname> オブジェクトには、複数の
53             <classname>Zend_Db_Table_Row</classname> オブジェクトが含まれます。
54             詳細については <link linkend="zend.db.table.rowset">table rowset</link> についての章を参照ください。
55         </para>
57         <example id="zend.db.table.row.read.example-rowset">
59             <title>行セット内の行を読み込む例</title>
61             <programlisting language="php"><![CDATA[
62 $bugs = new Bugs();
63 $rowset = $bugs->fetchAll($bugs->select()->where('bug_status = ?', 1));
64 $row = $rowset->current();
65 ]]></programlisting>
67         </example>
69         <sect3 id="zend.db.table.row.read.get">
71             <title>行からのカラムの値の読み込み</title>
73             <para>
74                 <classname>Zend_Db_Table_Row_Abstract</classname> にはアクセサがあり、
75                 行のカラムをオブジェクトのプロパティとして参照できます。
76             </para>
78             <example id="zend.db.table.row.read.get.example">
80                 <title>行からカラムを読み込む例</title>
82                 <programlisting language="php"><![CDATA[
83 $bugs = new Bugs();
84 $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
86 // bug_description カラムの値を出力します
87 echo $row->bug_description;
88 ]]></programlisting>
90             </example>
92             <note>
94                 <para>
95                     初期のバージョンの <classname>Zend_Db_Table_Row</classname> では、
96                     これらのアクセサをデータベースのカラムと対応させる際に
97                     <emphasis>inflection (変形)</emphasis>
98                     と呼ばれる文字列変換を行っていました。
99                 </para>
101                 <para>
102                     現在の <classname>Zend_Db_Table_Row</classname> では変形を実装していません。
103                     使用するアクセサ名は、データベース内のカラム名と正確に一致します。
104                 </para>
106             </note>
108         </sect3>
110         <sect3 id="zend.db.table.row.read.to-array">
112             <title>行データの配列としての取得</title>
114             <para>
115                 行のデータに対して配列としてアクセスするには、行オブジェクトの
116                 <methodname>toArray()</methodname> メソッドを使用します。
117                 これは、カラム名とその値を関連付けた連想配列を返します。
118             </para>
120             <example id="zend.db.table.row.read.to-array.example">
122                 <title>toArray() メソッドの使用例</title>
124                 <programlisting language="php"><![CDATA[
125 $bugs = new Bugs();
126 $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
128 // 行オブジェクトから カラム名/値 の連想配列を取得します
129 $rowArray = $row->toArray();
131 // 通常の配列と同様に使用します
132 foreach ($rowArray as $column => $value) {
133     echo "カラム: $column\n";
134     echo "値:  $value\n";
136 ]]></programlisting>
138             </example>
140             <para>
141                 <methodname>toArray()</methodname> が返す配列は、更新できません。
142                 配列内の値を変更することは可能ですが、
143                 それをデータベースに保存することはできません。
144             </para>
146         </sect3>
148         <sect3 id="zend.db.table.row.read.relationships">
150             <title>関連するテーブルからのデータの取得</title>
152             <para>
153                 <classname>Zend_Db_Table_Row_Abstract</classname> クラスには、関連するテーブルから
154                 行や行セットを取得するメソッドが存在します。
155                 テーブルのリレーションについての詳細な情報は
156                 <link linkend="zend.db.table.relationships">リレーションシップ</link>
157                 を参照ください。
158             </para>
160         </sect3>
162     </sect2>
164     <sect2 id="zend.db.table.row.write">
166         <title>データベースへの行の書き込み</title>
168         <sect3 id="zend.db.table.row.write.set">
170             <title>行のカラムの値の変更</title>
172             <para>
173                 個々のカラムの値をアクセサで設定する方法は、
174                 カラムを読み込む場合と同様で、オブジェクトのプロパティを使用します。
175             </para>
177             <para>
178                 カラムのアクセサによる値の設定は、アプリケーション内の行データのカラムの値は変更しますが、
179                 それだけではまだデータベースにコミットされていません。コミットするには
180                 <methodname>save()</methodname> メソッドを使用します。
181             </para>
183             <example id="zend.db.table.row.write.set.example">
185                 <title>行のカラムの内容を変更する例</title>
187                 <programlisting language="php"><![CDATA[
188 $bugs = new Bugs();
189 $row = $bugs->fetchRow($bugs->select()->where('bug_id = ?', 1));
191 // ひとつあるいは複数のカラムの値を変更します
192 $row->bug_status = 'FIXED';
194 // データベース内の行を、新しい値で UPDATE します
195 $row->save();
196 ]]></programlisting>
198             </example>
200         </sect3>
202         <sect3 id="zend.db.table.row.write.insert">
204             <title>新しい行の挿入</title>
206             <para>
207                 指定したテーブルに新しい行を作成するには、テーブルクラスの
208                 <methodname>createRow()</methodname> メソッドを使用します。
209                 取得した行のフィールドに対してはオブジェクト指向のインターフェイスでアクセスできますが、
210                 <methodname>save()</methodname> メソッドをコールするまでは
211                 実際にデータベースの内容が変更されることはありません。
212             </para>
214             <example id="zend.db.table.row.write.insert.example">
216                 <title>テーブルに新しい行を作成する例</title>
218                 <programlisting language="php"><![CDATA[
219 $bugs = new Bugs();
220 $newRow = $bugs->createRow();
222 // アプリケーションに応じて適切にカラムの値を設定します
223 $newRow->bug_description = '...説明...';
224 $newRow->bug_status = 'NEW';
226 // 新しい行をデータベースに INSERT します
227 $newRow->save();
228 ]]></programlisting>
230             </example>
232             <para>
233                 <methodname>createRow()</methodname> メソッドのオプションの引数として、連想配列を渡すことができます。
234                 この連想配列では、新しい行のフィールドに代入する値を指定します。
235             </para>
237             <example id="zend.db.table.row.write.insert.example2">
239                 <title>テーブルに新しい行を作成し、値を代入する例</title>
241                 <programlisting language="php"><![CDATA[
242 $data = array(
243     'bug_description' => '...説明...',
244     'bug_status'      => 'NEW'
247 $bugs = new Bugs();
248 $newRow = $bugs->createRow($data);
250 // 新しい行をデータベースに INSERT します
251 $newRow->save();
252 ]]></programlisting>
254             </example>
256             <note>
258                 <para>
259                     <classname>Zend_Db_Table</classname> の初期のリリースでは、<methodname>createRow()</methodname>
260                     メソッドは <methodname>fetchNew()</methodname> という名前でした。
261                     今後は新しい名前を用いることを推奨しますが、
262                     過去との互換性を確保するため古い名前も使用できるようになっています。
263                 </para>
265             </note>
267         </sect3>
269         <sect3 id="zend.db.table.row.write.set-from-array">
271             <title>複数のカラムの値の変更</title>
273             <para>
274                 <classname>Zend_Db_Table_Row_Abstract</classname> の
275                 <methodname>setFromArray()</methodname> メソッドを使用すると、
276                 ひとつの行の複数のカラムを一度に設定できます。
277                 このメソッドには、カラム名と値を関連付けた連想配列を指定します。
278                 このメソッドは、新しい行の値を設定する場合や
279                 既存の行を更新する場合のどちらでも有用でしょう。
280             </para>
282             <example id="zend.db.table.row.write.set-from-array.example">
284                 <title>setFromArray() で新しい行の値を設定する例</title>
286                 <programlisting language="php"><![CDATA[
287 $bugs = new Bugs();
288 $newRow = $bugs->createRow();
290 // データを連想配列形式にします
291 $data = array(
292     'bug_description' => '...説明...',
293     'bug_status'      => 'NEW'
296 // すべてのカラムの値を一度に設定します
297 $newRow->setFromArray($data);
299 // 新しい行をデータベースに INSERT します
300 $newRow->save();
301 ]]></programlisting>
303             </example>
305         </sect3>
307         <sect3 id="zend.db.table.row.write.delete">
309             <title>行の削除</title>
311             <para>
312                 行オブジェクトで <methodname>delete()</methodname> メソッドをコールできます。
313                 これは、その行オブジェクトの主キーに対応するデータベースの行を削除します。
314             </para>
316             <example id="zend.db.table.row.write.delete.example">
318                 <title>行の削除の例</title>
320                 <programlisting language="php"><![CDATA[
321 $bugs = new Bugs();
322 $row = $bugs->fetchRow('bug_id = 1');
324 // この行を DELETE します
325 $row->delete();
326 ]]></programlisting>
328             </example>
330             <para>
331                 変更を適用するのに <methodname>save()</methodname> をコールする必要はありません。
332                 これは、データベースに対して即時に適用されます。
333             </para>
335         </sect3>
337     </sect2>
339     <sect2 id="zend.db.table.row.serialize">
341         <title>行のシリアライズと復元</title>
343         <para>
344             データベースの行の内容を保存しておき、
345             あとで使用するということはよくありがちです。
346             オブジェクトの内容を、オフラインで保存しやすい形式 (たとえばファイルなど)
347             に変換するような処理のことを <emphasis>シリアライズ</emphasis> といいます。
348             <classname>Zend_Db_Table_Row_Abstract</classname> 型のオブジェクトは、
349             シリアライズできます。
350         </para>
352         <sect3 id="zend.db.table.row.serialize.serializing">
354             <title>行のシリアライズ</title>
356             <para>
357                 <acronym>PHP</acronym> の <methodname>serialize()</methodname> 関数を使用して、
358                 行オブジェクトのバイトストリームを含む文字列を作成します。
359             </para>
361             <example id="zend.db.table.row.serialize.serializing.example">
363                 <title>行のシリアライズの例</title>
365                 <programlisting language="php"><![CDATA[
366 $bugs = new Bugs();
367 $row = $bugs->fetchRow('bug_id = 1');
369 // オブジェクトをシリアライズします
370 $serializedRow = serialize($row);
372 // これで、$serializedRow をファイルなどに書き出すことができます
373 ]]></programlisting>
375             </example>
377         </sect3>
379         <sect3 id="zend.db.table.row.serialize.unserializing">
381             <title>シリアライズした行データの復元</title>
383             <para>
384                 <acronym>PHP</acronym> の <methodname>unserialize()</methodname> 関数を使用して、
385                 オブジェクトのバイトストリームを含む文字列を復元します。
386                 この関数は、もとのオブジェクトを返します。
387             </para>
389             <para>
390                 返された行オブジェクトは、
391                 <emphasis>接続が切断された</emphasis> 状態であることに注意しましょう。
392                 行オブジェクトやそのプロパティを読み込むことはできますが、
393                 その値を変更することはできません。また、データベース接続を必要とするようなメソッド
394                 (たとえば従属テーブルに対するクエリなど) も実行できません。
395             </para>
397             <example id="zend.db.table.row.serialize.unserializing.example">
399                 <title>シリアライズした行の復元の例</title>
401                 <programlisting language="php"><![CDATA[
402 $rowClone = unserialize($serializedRow);
404 // これでオブジェクトのプロパティを使用できますが、読み込み専用です
405 echo $rowClone->bug_description;
406 ]]></programlisting>
408             </example>
410             <note>
412                 <title>復元した行は、なぜ切断された状態なのですか?</title>
414                 <para>
415                     シリアライズしたオブジェクトは、可読形式の文字列となります。
416                     データベースのアカウントやパスワードといった情報を
417                     暗号化せずにプレーンテキストにシリアライズして保存すると、
418                     セキュリティ上問題となります。
419                     そのようなデータを無防備な状態でテキストファイルに保存したりしたくはないでしょう。
420                     またメールなどで攻撃者に覗き見られることも好まないはずです。
421                     シリアライズされたオブジェクトは、
422                     正しい認証情報を知らない限りデータベースにアクセスすることはできません。
423                 </para>
425             </note>
427         </sect3>
429         <sect3 id="zend.db.table.row.serialize.set-table">
431             <title>生きたデータとしての行の復活</title>
433             <para>
434                 切断された行の接続を復活させるには、
435                 <methodname>setTable()</methodname> メソッドを使用します。このメソッドへの引数としては、
436                 <classname>Zend_Db_Table_Abstract</classname> 型のオブジェクトを作成して渡します。
437                 テーブルオブジェクトを作成するには、データベースとの接続が必要です。
438                 そのテーブルと行を関連付けることで、行がデータベースにアクセスできるようになります。
439                 それ以降は、行オブジェクトの値を変更してデータベースに保存できるようになります。
440             </para>
442             <example id="zend.db.table.row.serialize.set-table.example">
444                 <title>行の復活の例</title>
446                 <programlisting language="php"><![CDATA[
447 $rowClone = unserialize($serializedRow);
449 $bugs = new Bugs();
451 // この行をテーブルに再接続し、
452 // データベースとの接続を復活させます
453 $rowClone->setTable($bugs);
455 // これで、行の内容を変更して保存できます
456 $rowClone->bug_status = 'FIXED';
457 $rowClone->save();
458 ]]></programlisting>
460             </example>
462         </sect3>
464     </sect2>
466     <sect2 id="zend.db.table.row.extending">
468         <title>行クラスの拡張</title>
470         <para>
471             <classname>Zend_Db_Table_Row</classname> は、<classname>Zend_Db_Table_Row_Abstract</classname>
472             を継承したデフォルトの具象クラスです。
473             <classname>Zend_Db_Table_Row_Abstract</classname> を継承した具象クラスを新たに作成し、
474             それを用いて行のインスタンスを作成できます。
475             独自の行クラスを指定するには、テーブルクラスの protected
476             メンバである <varname>$_rowClass</varname> を使用するか、
477             テーブルオブジェクトのコンストラクタの引数の配列で指定します。
478         </para>
480         <example id="zend.db.table.row.extending.example">
482             <title>独自の行クラスの指定</title>
484             <programlisting language="php"><![CDATA[
485 class MyRow extends Zend_Db_Table_Row_Abstract
487     // ...独自の処理
490 // 独自の行を、テーブルクラスの全インスタンスで
491 // デフォルトとして使用するように設定します
492 class Products extends Zend_Db_Table_Abstract
494     protected $_name = 'products';
495     protected $_rowClass = 'MyRow';
498 // あるいは、テーブルクラスの特定のインスタンスでのみ
499 // 独自の行クラスを使用するように設定します
500 $bugs = new Bugs(array('rowClass' => 'MyRow'));
501 ]]></programlisting>
503         </example>
505         <sect3 id="zend.db.table.row.extending.overriding">
506             <title>行の初期化</title>
508             <para>
509                 行を作成する際にアプリケーション固有のロジックを初期化したい場合は、
510                 その作業を <methodname>init()</methodname> メソッドに移動します。
511                 このメソッドは、行のメタデータの処理がすべて終わった後にコールされます。
512                 メタデータを変更するつもりがないのなら、
513                 <methodname>__construct()</methodname> メソッドを使うよりもこちらのほうを推奨します。
514             </para>
516             <example id="zend.db.table.row.init.usage.example">
517                 <title>init() メソッドの使用例</title>
519                 <programlisting language="php"><![CDATA[
520 class MyApplicationRow extends Zend_Db_Table_Row_Abstract
522     protected $_role;
524     public function init()
525     {
526         $this->_role = new MyRoleClass();
527     }
529 ]]></programlisting>
530             </example>
531         </sect3>
533         <sect3 id="zend.db.table.row.extending.insert-update">
535             <title>Zend_Db_Table_Row における Insert、Update および Delete の独自ロジックの定義</title>
537             <para>
538                 行クラスは、<constant>INSERT</constant> や <constant>UPDATE</constant>、
539                 <constant>DELETE</constant> の操作の前に、対応する protected メソッド
540                 <methodname>_insert()</methodname>、<methodname>_update()</methodname>
541                 および <methodname>_delete()</methodname> をコールします。
542                 行クラスのサブクラスで、これらのメソッドに独自ロジックを追加できます。
543             </para>
545             <para>
546                 特定のテーブルに対して独自のロジックを必要とし、
547                 それがそのテーブル上のすべての操作に対して発生するのなら、
548                 その処理はテーブルクラスの
549                 <methodname>insert()</methodname>、<methodname>update()</methodname> および
550                 <methodname>delete()</methodname> で実装したほうがよいでしょう。
551                 しかし、独自のロジックを行クラスで実装したほうがよい場合もあります。
552             </para>
554             <para>
555                 独自ロジックの実装を
556                 テーブルクラスよりも行クラスで行ったほうがよい例を、
557                 以下にいくつか示します。
558             </para>
560             <example id="zend.db.table.row.extending.overriding-example1">
562                 <title>行クラスでの独自ロジックの例</title>
564                 <para>
565                     独自ロジックが、そのテーブルのすべての操作に適用されるとは限りません。
566                     状況に応じて独自ロジックを適用するには、
567                     そのロジックを行クラスで実装し、
568                     その行クラスを指定してテーブルクラスのインスタンスを作成します。
569                     指定しなければ、テーブルクラスはデフォルトの行クラスを使用します。
570                 </para>
572                 <para>
573                     このテーブルでは、データに対する操作内容を <classname>Zend_Log</classname>
574                     オブジェクトに記録する必要があります。
575                     ただし、それはアプリケーションの設定でログ記録を有効にしている場合のみとします。
576                 </para>
578                 <programlisting language="php"><![CDATA[
579 class MyLoggingRow extends Zend_Db_Table_Row_Abstract
581     protected function _insert()
582     {
583         $log = Zend_Registry::get('database_log');
584         $log->info(Zend_Debug::dump($this->_data,
585                                     "INSERT: $this->_tableClass",
586                                     false)
587                   );
588     }
591 // $loggingEnabled はサンプルとして使用するプロパティで、
592 // これはアプリケーションの設定によって決まるものとします
593 if ($loggingEnabled) {
594     $bugs = new Bugs(array('rowClass' => 'MyLoggingRow'));
595 } else {
596     $bugs = new Bugs();
598 ]]></programlisting>
600             </example>
602             <example id="zend.db.table.row.extending.overriding-example2">
604                 <title>挿入するデータの記録を複数のテーブルで行う行クラスの例</title>
606                 <para>
607                     複数のテーブルで、共通の独自ロジックを使用することもあるでしょう。
608                     同じロジックをすべてのテーブルクラスで実装するのではなく、
609                     その場合はその動作を行クラスで定義しましょう。
610                     そして各テーブルでその行クラスを使用するのです。
611                 </para>
613                 <para>
614                     この例では、ログ記録用のコードは全テーブルクラスで同一です。
615                 </para>
617                 <programlisting language="php"><![CDATA[
618 class MyLoggingRow extends Zend_Db_Table_Row_Abstract
620     protected function _insert()
621     {
622         $log = Zend_Registry::get('database_log');
623         $log->info(Zend_Debug::dump($this->_data,
624                                     "INSERT: $this->_tableClass",
625                                     false)
626                   );
627     }
630 class Bugs extends Zend_Db_Table_Abstract
632     protected $_name = 'bugs';
633     protected $_rowClass = 'MyLoggingRow';
636 class Products extends Zend_Db_Table_Abstract
638     protected $_name = 'products';
639     protected $_rowClass = 'MyLoggingRow';
641 ]]></programlisting>
643             </example>
645         </sect3>
647         <sect3 id="zend.db.table.row.extending.inflection">
649             <title>Zend_Db_Table_Row における変形の定義</title>
651             <para>
652                 テーブルのクラス名を <acronym>RDBMS</acronym> のテーブル名とあわせるために、
653                 <emphasis>inflection (変形)</emphasis>
654                 と呼ばれる文字列変換を使用することを好む方もいます。
655             </para>
657             <para>
658                 <classname>Zend_Db</classname> クラス群は、デフォルトでは変形をサポートしていません。
659                 この方針については <link
660                     linkend="zend.db.table.extending.inflection">語尾変化の拡張</link>
661                 で説明します。
662             </para>
664             <para>
665                 変形をさせたい場合は、変換処理を自前で実装する必要があります。そのためには、
666                 独自の行クラスで <methodname>_transformColumn()</methodname> メソッドをオーバーライドし、
667                 テーブルクラスでクエリを実行する際にその独自行クラスを使用します。
668             </para>
670             <example id="zend.db.table.row.extending.inflection.example">
672                 <title>変換処理の定義例</title>
674                 <para>
675                     これにより、カラム名を変形させたものでアクセスできるようになります。
676                     行クラスの <methodname>_transformColumn()</methodname>
677                     メソッドを使用して、データベースのテーブル内のカラム名を変更しています。
678                 </para>
680                 <programlisting language="php"><![CDATA[
681 class MyInflectedRow extends Zend_Db_Table_Row_Abstract
683     protected function _transformColumn($columnName)
684     {
685         $nativeColumnName = myCustomInflector($columnName);
686         return $nativeColumnName;
687     }
690 class Bugs extends Zend_Db_Table_Abstract
692     protected $_name = 'bugs';
693     protected $_rowClass = 'MyInflectedRow';
696 $bugs = new Bugs();
697 $row = $bugs->fetchNew();
699 // キャメルケース形式のカラム名を使用します。
700 // 変換関数により、これをデータベース内での実際の形式に
701 // 変換します。
702 $row->bugDescription = 'New description';
703 ]]></programlisting>
705             </example>
707             <para>
708                 変換関数を書くのはあなたの役割です。
709                 Zend Framework では、そのような関数は用意していません。
710             </para>
712         </sect3>
714     </sect2>
716 </sect1>
717 <!--
718 vim:se ts=4 sw=4 et: