Maison >php教程 >PHP开发 >Implémentation de l'association multi-tables Yii2 ActiveRecord et de la recherche d'associations multi-tables

Implémentation de l'association multi-tables Yii2 ActiveRecord et de la recherche d'associations multi-tables

高洛峰
高洛峰original
2016-12-23 16:52:301373parcourir

ActiveRecord de Yii est une classe qui traite des bases de données, qui est le M (couche modèle) dans MVC et le O (Object) d'ORM.

Une question courante. Récemment, grâce aux retours du groupe, j'ai l'impression que beaucoup de gens ne comprennent toujours pas ce problème. Aujourd'hui, j'ai expliqué clairement ce problème. Jetons un coup d'œil à l'association multi-tables de yii2 ActiveRecord et comment optimiser cette association.

Exigences du scénario :

Supposons que nous ayons une table utilisateur user et une table de canal utilisateur auth. Les deux tables de données sont liées un à un via user.id et auth.uid. Il est maintenant nécessaire d'afficher la source du canal source de la table d'authentification dans la liste des utilisateurs, et le canal doit pouvoir être recherché.

Nous générons d’abord des modèles et des opérations liés aux utilisateurs et aux séries d’authentification via gii. Aucune explication détaillée n'est donnée ici. Pour les opérations gii, veuillez vous référer à xxx

Je pense que nous allons continuer à examiner les étapes importantes :

1 Trouvez la classe de modèle AR commonmodelsUser.php correspondante. à la table user. , associez la table auth

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

dans ce type de fichier

Après l'avoir configurée, cela ne veut pas dire que les deux données. les tables seront automatiquement associées ! Nous visitons la page de liste des utilisateurs (la page de liste est générée par gii, nous ne l'avons pas exploitée jusqu'à présent). En visualisant les requêtes de base de données via le débogage, il n'est pas difficile de constater que la requête réelle n'est pas associée à la table d'authentification <.>

2. Dans la grille Ajouter le champ source canal source

<?= GridView::widget([
// other codes
&#39;columns&#39; => [
// other columns
&#39;auth.source&#39;,
]
]); ?>
dans la table d'association .source ?

Ne vous inquiétez pas, nous ouvrons maintenant le débogage pour voir la requête réelle.

Nous constaterons qu'il existe de nombreuses opérations comme select * from `auth` où uid = xxx;. Si votre pagination est par défaut sur 20 éléments de données, il y aura 20 requêtes similaires.

Voyons d’abord ce qui s’est passé ?

En fait, c'est la connaissance de base de php. Lors de la lecture ou de l'écriture d'une variable membre inexistante d'un objet, les fonctions magiques __get() __set() sont automatiquement appelées. Yii en profite également pour l'implémenter !

Cette opération est presque la même que la méthode d'encapsulation de la plupart des gens dans GridView pour obtenir les données de table associées, mais ! 20 requêtes SQL augmentent évidemment beaucoup de frais généraux. Ce serait génial s'il s'agissait d'une opération de jointure à gauche !

3. Optimiser SQL

Ce que nous devons optimiser est :

20 modifications SQL en 1 SQL

Obtenir uniquement les champs requis par la table associée

Certains étudiants crient, voici le fonctionnement qui vient avec Yii, comment l'optimiser ? Nous revenons à l'acquisition des sources de données et constatons que les données de la liste d'utilisateurs sont fournies via la méthode de recherche du modèle userSearch.

C'est-à-dire que notre requête de données n'effectue pas réellement de requête de table associée ! Dans ce cas, nous ajoutons la requête associée

à UserSearch

$query = User::find();
$query->joinWith([&#39;auth&#39;]);
$query->select("user.*, auth.source");
Actualisons à nouveau la page de la liste des utilisateurs, puis grâce à l'analyse de débogage, nous constatons qu'il y a sont deux sql causés Notre attention

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);
En d'autres termes, nous avons atteint l'objectif d'optimiser SQL grâce à l'analyse de débogage, nous avons constaté que le temps de requête. de DB a été beaucoup réduit.

4. Ajouter une requête aux champs de table associés

Le modèle de recherche dans GridView est également implémenté via searchModel, qui contrôle quels champs peuvent être recherchés et quels champs ne peuvent pas être recherchés via des règles.

Nous devons maintenant rendre la source de la table d'association consultable, nous définissons donc une source d'attribut dans le searchModel et l'ajoutons aux règles

public $source;
public function rules()
{
return [
// other rules
[&#39;source&#39;, &#39;safe&#39;],
];
}
Ensuite, nous modifions le auth.source dans la grille

// &#39;auth.source&#39;,
[
&#39;attribute&#39; => &#39;source&#39;,
&#39;value&#39; => &#39;auth.source&#39;,
&#39;label&#39; => &#39;渠道来源&#39;,
],
À ce stade, notre interface est ok, mais nous devons encore implémenter recherche sur le programme. Une étape plus loin, nous pouvons ajouter de nouvelles conditions de source où la source de données est obtenue

$query->andFilterWhere([
// other params
&#39;auth.source&#39; => $this->source,
]);
Permettez-moi d'ajouter quelques utilisations d'ActiveRecord dans Yii.

1, objet au tableau

$model = new ActiveRecord();

$model.toArray();

Puisque ActiveRecord n'est pas un simple tableau. , il ne peut pas être directement json_encoded , sinon les informations sont incomplètes.

Solution : $model.toArray(); Cela le transforme en un simple tableau et peut être json_encoded.

2. Obtenez l'identifiant ActiveRecord directement via le nom ou d'autres champs.

$nIdcId = idc_info::model()->find(&#39;name like :name&#39;,array(&#39;:name&#39;=>"%".$strIdcName."%"))->id;
La méthode que j'utilisais souvent avant est (maintenant je la trouve très ennuyeuse) :

$idc = Idc::model()->find("...");
$id = $idc->id;
3. Compréhension du modèle

$accModel = call_user_func(array(ActiveRecordName, &#39;model&#39;));
$model  = $accModel->findByPk($id);
Ce qui précède est l'association multi-tables Yii2 ActiveRecord introduite. par l'éditeur. J'espère que ces connaissances sur la mise en œuvre de la recherche d'associations de tables vous seront utiles. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois !

Pour plus d'articles liés à la mise en œuvre de l'association multi-tables Yii2 ActiveRecord et de la recherche d'associations multi-tables, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn