À propos de l'analyse des requêtes liées à YII

不言
Libérer: 2023-04-01 09:56:01
original
1255 Les gens l'ont consulté

Cet article présente principalement les informations pertinentes de la requête de corrélation YII. Les amis qui en ont besoin peuvent s'y référer

1 Configuration de la corrélation multi-tables

Avant d'utiliser AR pour effectuer des requêtes associées, nous devons faire savoir à AR comment une classe AR est liée à une autre.

La relation entre deux classes AR est directement liée à travers la relation entre les tableaux de données représentés par les classes AR. Du point de vue d'une base de données, il existe trois types de relations entre les tables A et B : un-à-plusieurs (comme tbl_user et tbl_post), un-à-un (comme tbl_user et tbl_profile) et plusieurs-à-plusieurs ( plusieurs à plusieurs tels que tbl_category et tbl_post). En AR, il existe quatre relations :

BELONGS_TO (appartient à) : Si la relation entre les tables A et B est un-à-plusieurs, alors la table B appartient à la table A (par exemple, Post appartient à l'utilisateur );

HAS_MANY (il y en a plusieurs) : si la relation entre les tables A et B est de un à plusieurs, alors A a plusieurs B (par exemple, l'utilisateur a plusieurs publications

HAS_ONE (il y en a un) : Il s'agit d'un cas particulier de HAS_MANY : A peut avoir au plus un B (par exemple, l'utilisateur peut avoir au plus un profil

MANY_MANY : cela correspond aux plusieurs-) ; relation à plusieurs dans la base de données. Étant donné que la plupart des SGBD ne prennent pas directement en charge les relations plusieurs-à-plusieurs, une table de relations est nécessaire pour diviser la relation plusieurs-à-plusieurs en une relation un-à-plusieurs. Dans notre exemple de structure de données, tbl_post_category est utilisé à cette fin. En termes AR, nous pouvons interpréter MANY_MANY comme la combinaison de BELONGS_TO et HAS_MANY. Par exemple, Post appartient à plusieurs (appartient à plusieurs) Catégorie et Catégorie a plusieurs (a plusieurs) Post.

La relation définie dans AR doit remplacer la méthode relations() dans CActiveRecord. Cette méthode renvoie un tableau de configurations de relations. Chaque élément du tableau représente une relation unique au format suivant.

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)
Copier après la connexion

où VarName est le nom de la relation ; RelationType spécifie le type de relation, qui peut être l'une des quatre constantes suivantes : self::BELONGS_TO , self:: HAS_ONE, self::HAS_MANY et self::MANY_MANY ; ClassName est le nom de la classe AR associée à cette classe AR ; ForeignKey spécifie la clé étrangère (une ou plusieurs) utilisée dans la relation.

Quelques points qui méritent d'être clarifiés :

(1), à quoi fait référence VarName ? Voir l'exemple 2 ci-dessous pour plus de détails.


(2), Type de relation. Il existe 4 types au total, à savoir

self::HAS_MANY, self::BELONGS_TO, self::MANY_MANY, self::HAS_ONE.


(3), Nom de classe. Autrement dit, un autre ../model/classname.php associé.


(4), Clé étrangère. Qui est la clé étrangère pour qui ?


(5), conditions supplémentaires

Diagramme ER

Exemple 1, relation un-à-plusieurs et plusieurs-à-un (relation entre la publication et l'utilisateur )

1) models/Post.php

class Post extends CActiveRecord 
{ 
...... 
public function relations() 
{ 
return array( 
'author'=>array(self::BELONGS_TO, 'User', 'author_id'), 
); 
} 
}
Copier après la connexion

La relation entre Post et Utilisateur est BELONGS_TO ( plusieurs paires 1) relation et est associé à l'utilisateur via l'author_id de Post.


L'author_id dans Post est une clé étrangère et est associé à l'utilisateur.


Remarque : VarName est ici l'auteur, un objet.

(2)models/User.php

class User extends CActiveRecord 
{ 
...... 
public function relations() 
{ 
return array( 
'posts'=>array(self::HAS_MANY, 'Post', 'author_id'), 
'profile'=>array(self::HAS_ONE, 'Profile', 'owner_id'), 
); 
} 
}
Copier après la connexion

Pour l'utilisateur, la relation avec Post est HAS_MANY relation (un-à-plusieurs). Et associé à Post via author_id de Post.

Exemple 2, relation plusieurs-à-plusieurs

dans FailParts.php

'Users' => array(self::MANY_MANY, 'User', 'fail_parts_user(fail_parts_id, user_id)'),
Copier après la connexion

Dans User.php

'FailParts' => array(self::MANY_MANY, 'FailParts', 'fail_parts_user(user_id, fail_parts_id)'),
Copier après la connexion

Étant donné que les deux ont une relation plusieurs-à-plusieurs, les utilisateurs doivent être utilisés à la place de l'utilisateur ; utilisez FailParts au lieu de FailPart.

Les utilisateurs et les FailParts ici sont le VarName précédent.

Exemple 3, relation un-à-un

Il est relativement simple et sera omis pour l'instant.

2, à propos de VarName.

Pour la classe A.php, 'VarName'=>array('RelationType', 'B', 'ForeignKey', ...options supplémentaires)

où VarName est fondamentalement le même que B. Mais pas forcément exactement la même chose. À ce stade, vous pouvez accéder à B et à ses valeurs d'attribut via VarName dans le view/A/xx.php de A.

Si c'est un-à-un : A->VarName

S'il s'agit de plusieurs-à-un : author_name = $post->Author->name
Si c'est un-à-un : A->Author->name; est un à plusieurs : $posts = $author->Post
S'il s'agit de plusieurs à plusieurs : $posts = $author->Post;//L'essence est de le diviser en un-à-plusieurs : $posts = $author->Post; à plusieurs et plusieurs à un

foreach($posts as $u){ 
$_tmp_titles[] = $u -> title; 
} 
titleStr = implode(', ', $_tmp_titles);
Copier après la connexion

2. L'utilisation d'associations multi-tables

souvent dans les contrôleurs

1, Chargement retardé

(1) Plusieurs-à-un

$post = Post::model()->findByPk(10); 
$author = $post->author;
Copier après la connexion
Remarque : L'essence ici est individuelle.

(2) Un-à-plusieurs

$user = User::model()->findByPk(10); 
$posts = $user->posts;
Copier après la connexion
(3) Plusieurs-à-plusieurs

Il est important de noter : il existe une relation séquentielle entre les deux identifiants.

Du point de vue de l'instance $repairInfo, l'association doit être

'FailParts' => array(self::MANY_MANY, 'FailParts', 'repair_mapping(repair_info_id,fail_parts_id)'),
Copier après la connexion

Du point de vue de l'instance $failParts, l'association La relation devient

'RepairInfos' => array(self::MANY_MANY, 'RepairInfo', 'repair_mapping(fail_parts_id, repair_info_id)'),
Copier après la connexion

Comme indiqué précédemment, il n'est pas nécessaire de configurer les deux parties, seule la partie requise peut la définir.

Méthode stupide utilisée avant :

/*方法一:使用表关系(多对多)*/ 
$fails = $repairInfo->FailParts;//在$repairInfo中使用 
/*方法二:使用原始方法*/ 
$id = $repairInfo->id; 
$maps = RepairMapping::model()->findAll("repair_info_id = $id"); 
$f_ids = array(); 
foreach($maps as $map){ 
array_push($f_ids, $maps[0]->fail_parts_id); 
} 
$f_idsStr = implode(',',$f_ids); 
$fails = FailParts::model()->findAll("id IN ($f_idsStr)");
Copier après la connexion

2, chargement actif - avec

(1) Un à plusieurs

(2) Plusieurs à plusieurs

$posts = Post::model()->('author')->findAll();
Copier après la connexion

例子:

User.php

//查询一个机房$idc_id的所有用户 
function getAdminedUsersByIdc($idc_id){ 
$c = new CDbCriteria(); 
$c->join = "JOIN idc_user on t.id=idc_user.user_id"; 
$c->condition = "idc_user.idc_id=$idc_id"; 
return User::model()->with('Idcs')->findAll($c); 
} 
//规则中配置 
'Idcs' => array(self::MANY_MANY, 'Idc', 'idc_user(user_id, idc_id)'),
Copier après la connexion

批注:没有with('Idcs'),执行后的结果也一样。只不过不再是eager loading。

三、带参数的关联配置

常见的条件有

1,condition 按某个表的某个字段加过滤条件

例如:

//在User的model里定义,如下关联关系 
'doingOutsources' => array(self::MANY_MANY, 'Outsource', 'outsource_user(user_id, outsource_id)', 
'condition' => "doingOutsources.status_id IN(" . Status::ASSIGNED . "," . Status::STARTED ."," . Status::REJECTED .")"),
Copier après la connexion

//结论:condition是array里指定model的一个字段。

显然,doingOutsources是真实数据表Outsource的别名,所以在condition中可以使用doingOutsources.status_id,当然也可以使用Outsource.status_id。另本表名user的默认别名是t。

2,order 按某个表的某个字段升序或降序

//在RepairInfo的model里定义,如下关联关系 
'WorkSheet' => array(self::HAS_MANY, 'WorkSheet', 'repair_info_id', order => 'created_at desc'), 
//调用 
$worksheets = $repair_info->WorkSheet; //此时$worksheets是按降序排列
Copier après la connexion

//结论:order是array里指定model的一个字段。

with
joinType
select
params
on
alias
together
group
having
index

还有用于lazy loading的
limit 只取5个或10个
offset
through
官方手册
'posts'=>array(self::HAS_MANY, 'post', 'author_id', 'order'=>'posts.create_time DESC', 'with'=>'categories'),

四、静态查询(仅用于HAS_MANY和MANY_MANY)

关键字:self:STAT

1,基本用法。例如,

class Post extends CActiveRecord 
{ 
...... 

public function relations() 
{ 
return array( 
'commentCount'=>array(self::STAT, 'Comment', 'post_id'), 
'categoryCount'=>array(self::STAT,'Category','post_category(post_id, category_id)'); 

); 
} 
}
Copier après la connexion

2,静态查询也支持上面的各种条件查询

'doingOutsourceCount' => array(self::STAT, 'Outsource', 'outsource_user(user_id, outsource_id)', 
'condition' => "outsource.status_id IN(" . Status::ASSIGNED . "," . Status::STARTED ."," . Status::REJECTED .")"),
Copier après la connexion

其他查询还包括

condition 使用较多

order
select
defaultValue
params
group
having

3,静态查询的加载方式

可以使用lazy loading方式
$post->commentCount.
也可以使用eager loading方式
$posts = Post::model()->with('commentCount','categoryCount')->findAll();
注with中字符串一定是别名。

两者的性能比较:

如果需要取所有post的所有comment,前者需要2N+1次查询,而后者只有一次。两者的选择视情况而定。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

Yii中表单用法实例

Yii2如何实现同时搜索多个字段

如何实现Yii2框架中使用PHPExcel导出Excel文件

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!