アクティブ レコード (AR) を使用して単一のデータ テーブルからデータを取得する方法について見てきました。 このセクションでは、AR を使用して複数の関連データ テーブルを接続し、結合されたデータ セットを取得する方法について説明します。
リレーショナル AR を使用するには、関連付ける必要があるテーブルに主キーと外部キーの制約を定義することをお勧めします。これらの制約は、関連データの一貫性と整合性を確保するのに役立ちます。
このサンプルでは、Yii Framework Development Tutorial (25) Database-Query Builder Example を変更して、複数の関連テーブルに対して Active Record を使用する方法を紹介します。
AR を使用して関連クエリを実行する前に、ある AR クラスが別の AR クラスにどのように関連しているかを AR に知らせる必要があります。
2 つの AR クラス間の関係は、AR クラスによって表されるデータ テーブル間の関係を通じて直接関連付けられます。 データベースの観点から見ると、テーブル A と B の間には 3 種類のリレーションシップがあります。1 対多 (tbl_user と tbl_post など)、1 対 1 (tbl_user と tbl_profile など)、および多対 1 多 ( tbl_category や tbl_post などの多対多)。 AR には 4 つの関係があります:
BELONGS_TO (所属): テーブル A と B の間の関係が 1 対多の場合、テーブル B はテーブル A に所属します (たとえば、Post はユーザー
に所属します)。 HAS_MANY (複数ある): テーブル A と B の関係が 1 対多の場合、A には複数の B があります (たとえば、User には複数の Post があります)
HAS_ONE (1 つあります): これは特殊なケースです。 HAS_MANY のうち、A には B が最大 1 つあります (たとえば、ユーザーにはプロファイルが最大 1 つあります);
MANY_MANY: これは、データベース内の多対多の関係に対応します。 ほとんどの DBMS は多対多の関係を直接サポートしていないため、多対多の関係を 1 対多の関係に分割するには関係テーブルが必要です。 この例のデータ構造では、tbl_post_category がこの目的に使用されます。 AR 用語では、MANY_MANY を BELONGS_TO と HAS_MANY の組み合わせとして解釈できます。 たとえば、Post は多くの カテゴリに属し、カテゴリには多くのカテゴリがあります。Post.
AR で定義された関係は、CActiveRecord の relationship() メソッドをオーバーライドする必要があります。このメソッドは、関係構成の配列を返します。配列の各要素は、次の形式で単一の関係を表します。
クエリ ビルダーでは、次の SQL クエリ ステートメントを使用しました
SELECT c.FirstName, c.LastName , c.Address,c.Email FROM customer c INNER JOIN employee e ON c.SupportRepId=e.EmployeeId
WHERE e.EmployeeId=4 には、Employee と Customer という 2 つのテーブルが含まれます。従業員と顧客の間には 1 対多の関係があり、従業員が責任者となることができます。複数のクライアント向け。従業員と顧客の関係は HAS_MANY で、顧客と従業員の関係は HAS_ONE です。したがって、Employee と Customer は次のように定義できます。
//Customer.phpclass Customer extends CActiveRecord{ public static function model($className=__CLASS__){return parent::model($className);} public function tableName(){return 'Customer';} } //Employee.phpclass Employee extends CActiveRecord{ public static function model($className=__CLASS__){return parent::model($className);} public function tableName(){return 'Employee';} public function relations(){return array('customers'=>array(self::HAS_MANY, 'Customer', 'SupportRepId'), );}}
この例では、Employee クエリに対応する Customer のみを使用するため、クラスには Relations メソッドのみが定義されます。対応するテーブルと外部キーは Customer と SupportRepId です。
次に、SiteController の IndexAction メソッドを変更します。
public function actionIndex(){ $employee=Employee::model()->findByPk(4); $this->render('index', array('model' => $employee->customers, ));}
AR クラスのリレーションシップ定義は、リレーションシップごとにクラスに属性を暗黙的に追加します。相関クエリが実行されると、対応する属性に、関連付けられた AR インスタンスが設定されます。したがって、従業員に対応する顧客レコードは、$employee->customers からクエリできます。
相関クエリを実行する最も簡単な方法は、AR インスタンスの相関プロパティを読み取ることです。このプロパティに以前にアクセスしたことがない場合は、現在の AR インスタンスの主キーを使用して 2 つのテーブルとフィルターを結合する結合クエリが初期化されます。 クエリ結果は、関連付けられた AR クラスのインスタンスとしてプロパティに保存されます。これは伝説的な遅延読み込み (遅延読み込み、遅延読み込みとも訳される) メソッドです。たとえば、関連クエリは、関連オブジェクトに初めてアクセスしたときにのみ実行されます。
この例では遅延読み込みを使用していますが、場合によっては効率的ではありません。 N 個の投稿の作成者を取得したい場合、この遅延読み込みを使用すると、N 個の結合クエリが実行されます。 この場合、代わりに積極的な読み込みを使用する必要があります。
積極的な読み込みメソッドは、メインの AR インスタンスを取得するときに、関連する AR インスタンスを取得します。 これは、AR で find または findAll メソッドを使用するときに with メソッドを使用して行われます。例:
$employee=Post::model()->with ('customers')->findAll();
最後に、結果を表示するビューのコードを変更します。
$customer){ echo 'First Name:' . $customer->FirstName . ''; echo 'Last Name:' . $customer->LastName . ''; echo 'Address:' . $customer->Address . ''; echo 'Email:' . $customer->Email . ''; echo '----------------------';} ?>
データが異なると、列名の大文字と小文字が区別されます。安全のため、同じ属性を使用します。列定義として Customer を大文字と小文字で表します。
この例では、関連付けられた Active Record の最も基本的な使用法を紹介します。また、CodeSmith などのツールを使用してデータベース定義の ActiveRecord コードを自動的に生成できる場合は、Yii の中国語ドキュメントを参照してください。プログラマーの手動コード作成の負担が大幅に軽減されます。
さらに、Active Record を使用すると便利ですが、パフォーマンスが犠牲になります。一般に、Active Record を使用した場合のパフォーマンスは、DAO を使用してデータベースを読み書きするよりも 1 レベル悪くなります。次の表は、200 人の俳優と 1000 本の映画を検索するための参考値です。
上記は、PHP 開発フレームワーク Yii Framework チュートリアル (27) データベース関連のアクティブ レコードの例の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。