Yii2 ActiveRecordのマルチテーブル関連付けとマルチテーブル関連付け検索の実装

高洛峰
リリース: 2016-12-23 16:52:30
オリジナル
1331 人が閲覧しました

YiiのActiveRecordはデータベースを扱うクラスで、MVCのM(モデル層)、ORMのO(オブジェクト)にあたります。

よくある質問。最近、グループ内でのフィードバックを通して、この問題をまだ理解していない人が多いと感じました。今日はこの問題についてわかりやすく説明しました。yii2 ActiveRecord の複数テーブルの関連付けと、この関連付けを最適化する方法を見てみましょう。

シナリオ要件:

ユーザー テーブル user とユーザー チャネル テーブル auth があり、2 つのデータ テーブルが user.id と auth.uid によって 1 対 1 に関連付けられているとします。ここで、認証テーブルのソース チャネル ソースをユーザー リストに表示する必要があり、チャネルが検索可能である必要があります。

まず、gii を通じてユーザーおよび認証シリーズ関連のモデルと操作を生成します。ここでは詳しい説明はありません。xxx

を参照してください。引き続き重要な手順を見ていきます。

1. ユーザー テーブルに対応する AR モデル クラス commonmodelsUser.php を見つけて関連付けます。このクラスファイルでは、認証テーブル

/**
* 关联auth表
*/
public function getAuth()
{
// hasOne要求返回两个参数 第一个参数是关联表的类名 第二个参数是两张表的关联关系
// 这里uid是auth表关联id, 关联user表的uid id是当前模型的主键id
return $this->hasOne(common\models\Auth::className(), ['uid' => 'id']);
}
ログイン後にコピー

が設定された後、2 つのデータテーブルが自動的に関連付けられるわけではありません。ユーザー リスト ページにアクセスします (リスト ページは GII によって生成されますが、これまでは操作していません)。デバッグを通じてデータベース クエリを表示すると、実際のクエリが認証テーブルに関連付けられていないことがわかります

2. グリッドビューのソースチャネルフィールドソースに関連付けテーブルを追加します

上記で auth.source を直接使用するにはどうすればよいか疑問に思う人もいます。

心配しないでください。デバッグを開いて実際のクエリを確認します。

select * from `auth` where uid = xxx; のような多くの操作があることがわかります。ページングのデフォルトが 20 個のデータである場合、同様のクエリが 20 個存在します。

まず何が起こったのか見てみましょう?

実はこれ、phpの基礎知識なんです。オブジェクトの存在しないメンバー変数を読み書きする場合、__get() __set() マジック関数が自動的に呼び出されます。 Yii もこれを利用して実装しています。

この操作は、ほとんどの人がグリッドビューでメソッドをカプセル化し、関連するテーブル データを取得するのとほぼ同じですが、! 20 個の SQL クエリでは、明らかにオーバーヘッドが大幅に増加します。これが左結合操作であれば素晴らしいでしょう。

3. SQL を最適化する

最適化する必要があるのは次のとおりです:

20 sql を 1 sql に変更します

関連するテーブルに必要なフィールドのみを取得します

いくつかの生徒が質問していますが、これが Yii に付属する操作です。それを最適化するにはどうすればよいですか?データ ソースの取得に戻り、ユーザー リストのデータが userSearch モデルの検索メソッドを通じて提供されていることがわかります。

つまり、データ クエリは実際には関連テーブル クエリを実行しません。この場合、UserSearch に関連クエリを追加します

<?= GridView::widget([
// other codes
&#39;columns&#39; => [
// other columns
&#39;auth.source&#39;,
]
]); ?>
ログイン後にコピー

ユーザー リスト ページを再度更新して、デバッグ分析を通じて、2 つの SQL ステートメントが注目を集めていることがわかります

$query = User::find();
$query->joinWith([&#39;auth&#39;]);
$query->select("user.*, auth.source");
ログイン後にコピー

つまり、SQL の最適化という目標は達成されました。デバッグ分析を通じて、DB のクエリ時間が大幅に短縮されたことがわかりました。

4. 関連するテーブル フィールドにクエリを追加します。

GridView の検索モデルも、searchModel を通じて実装され、どのフィールドが検索可能か、どのフィールドが検索不可能かを制御します。

次に、関連付けテーブルのソースを検索可能にする必要があるため、searchModel で属性ソースを定義し、それをルールに追加します

SELECT `user`.*, `auth`.`source` FROM `user` LEFT JOIN `auth` ON `user`.`id` = `auth`.`uid` LIMIT 20
SELECT * FROM `auth` WHERE `user_id` IN (20个uid);
ログイン後にコピー

次に、gridview で auth.source を変更します

public $source;
public function rules()
{
return [
// other rules
[&#39;source&#39;, &#39;safe&#39;],
];
}
ログイン後にコピー

この時点までのインターフェースは問題ありません。プログラムによる検索を実装するためのステップがまだ 1 つ残っています。データ ソースを取得する場所に新しいソース条件を追加するだけです

以下はActiveRecord

1 の一部の使用法、 object to array

$model = new ActiveRecord();

ActiveRecord は単純な配列ではないため、直接 json_encode することはできません。情報は不完全になります。

解決策: $model.toArray(); これにより、単純な配列に変換され、json_encode できるようになります。


2. 名前またはその他のフィールドから ActiveRecord ID を直接取得します。

// &#39;auth.source&#39;,
[
&#39;attribute&#39; => &#39;source&#39;,
&#39;value&#39; => &#39;auth.source&#39;,
&#39;label&#39; => &#39;渠道来源&#39;,
],
ログイン後にコピー

私が昔よく使っていた方法は次のとおりです(今ではとても下品だと思います):

$query->andFilterWhere([
// other params
&#39;auth.source&#39; => $this->source,
]);
ログイン後にコピー

3、モデルの理解

$nIdcId = idc_info::model()->find(&#39;name like :name&#39;,array(&#39;:name&#39;=>"%".$strIdcName."%"))->id;
ログイン後にコピー

上記はエディターは、Yii2 ActiveRecord マルチテーブル関連付けとマルチテーブル関連付け検索の実装に関する知識を皆さんに紹介します。ご質問があれば、メッセージを残してください。編集者がすぐに返信します。 。また、PHP 中国語 Web サイトをサポートしていただきありがとうございます。

Yii2 ActiveRecord マルチテーブル関連付けとマルチテーブル関連付け検索の実装に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート