If I have a class representing access to one table in my database in a class:table relationship, so I can hide table details in one class. But as any useful application I have to query several tables. How can I accomodate this using the class:table design?
1 に答える
これを実現する方法はいくつかありますが、どの方法を選択するかは状況によって異なります。
1) オブジェクトとデータベース間の接続を切断します
データベース テーブルと接続しないようにオブジェクトを記述します。最初にデータベース テーブルを正規化してから、アプリケーションのユーザーがデータをどのように操作するかを調べます。データをオブジェクトにモデル化しますが、各オブジェクトをテーブルに関連付けないでください (つまり、 Zend_DB_Table_Abstract クラスを使用します)。
オブジェクトを確立したら、オブジェクトをデータベース内の関連するテーブルにマップするマッパー クラスを記述します。これらは Zend_DB_Table を拡張するクラスです (該当する場合)。
結合は 2 つの方法で処理できます。Zend_DB_Table リレーションシップ機能を使用して結合をマップするか、または (IMHO の方が適切な選択です) Zend_DB_Select を使用してマッパー クラス内で関連するメソッドを作成します。
したがって、2 つのクラスがあります (おそらくテーブルごとですが、常にではありません)。
人物 PersonMapper
コードで、いくつかのオブジェクトを操作する場合は、新しいオブジェクトを作成します
$person = new Person();
$person->setName('andrew taylor');
次に、それをマッパーに渡して保存します。
$personMapper = new PersonMapper();
$pesonnMapper->save($person);
または、別の方法で実行します。
$personMapper = new PersonMapper();
$person = personMapper->load(29);
$person->setName('joe bloggs');
$personMapper->save($person);
ここからの次のステップは、 SPLに基づくコレクション クラスです。
$personList = $personMapper->loadAllMen();
foreach($personList AS $person) {
echo $person->getName();
}
$personMapper->loadAllMen() は次のようなメソッドです。
$select = $this->select();
$select=>where('gender = "Male"');
$zendDbRows = this->fetchAll($select);
return new PersonList($zendDbRows);
2) MySQL ビュー
結合ごとに 1 つの行がある多数の結合テーブルがある場合、orders テーブルの ID に基づいて顧客情報を結合していて、それを読み取り専用で行っています (したがって、 Zend_DB_Table アダプターを介して情報を更新します)、正規化されたテーブルを作成し、上部に単一のビューを作成します。ビューはバックグラウンドで結合を処理するため、Zend を介して単一のテーブルに接続しているように感じます。
これには注意点がいくつかあります。MySQL ビューにはパフォーマンス上の問題があり (これが単一行の FK 結合に最適な理由です)、厳密には読み取り専用です。