Zend Framework のテーブル リレーションシップ機能を設計および実装しました。
私の最初のコメントは、findDependentRowset()
とにかく使用しないということですfindParentRow()
。アクションにユーザーへの外部キー参照がある場合に使用します。
$actionTable = new Action();
$actionRowset = $actionTable->fetchAll();
foreach ($actionRowset as $actionRow) {
$userRow = $actionRow->findParentRow('User');
}
編集: ループには $actionRow と $userRow オブジェクトがあります。オブジェクト フィールドを変更しsave()
てオブジェクトを呼び出すことにより、いずれかのオブジェクトを介して変更をデータベースに書き戻すことができます。
Zend_Db_Table_Select クラス (私がプロジェクトを離れた後に実装されたもの) を使用して、Action と User の間の結合に基づいて Rowset を取得することもできます。
$actionTable = new Action();
$actionQuery = $actionTable->select()
->setIntegrityCheck(false) // allows joins
->from($actionTable)
->join('user', 'user.id = action.user_id');
$joinedRowset = $actionTable->fetchAll($actionQuery);
foreach ($joinedRowset as $joinedRow) {
print_r($joinedRow->toArray());
}
結合クエリに基づくこのような Rowset は読み取り専用であることに注意してください。save()
行オブジェクトにフィールド値を設定して、変更をデータベースにポストバックする呼び出しを行うことはできません。
編集:任意の結合された結果セットを書き込み可能にする方法はありません。上記の結合された結果セットに基づく簡単な例を考えてみましょう。
action_id action_type user_id user_name
1 Buy 1 Bill
2 Sell 1 Bill
3 Buy 2 Aron
4 Sell 2 Aron
次に、action_id=1 の行について、User オブジェクトから取得したフィールドの 1 つを変更します。
$joinedRow->user_name = 'William';
$joinedRow->save();
質問: action_id=2 の次の行を表示すると、'Bill' と 'William' のどちらが表示されますか? 「William」の場合、行 1 を保存すると、この結果セットの他のすべての行で「Bill」が「William」に自動的に更新されなければならないということですか? それともsave()
、SQL クエリを自動的に再実行して、データベースから更新された結果セットを取得するという意味ですか? クエリに時間がかかる場合はどうすればよいですか?
オブジェクト指向の設計も考慮してください。各行は個別のオブジェクトです。1 つのオブジェクトを呼び出すとsave()
、別のオブジェクトの値が変更されるという副作用があることは適切ですか (オブジェクトの同じコレクションの一部であっても)。これは、コンテンツ カップリングの一種のように思えます。
上記の例は比較的単純なクエリですが、より複雑なクエリも使用できます。Zend_Db は、書き込み可能な結果と読み取り専用の結果を区別する目的でクエリを分析することはできません。これが、MySQL ビューが更新できない理由でもあります。