Cet article présente principalement les informations pertinentes sur la requête liée à YII. Les amis dans le besoin peuvent s'y référer. J'espère que cela aide tout le monde.
1. Configuration de la corrélation multi-tables
Avant d'utiliser AR pour effectuer des requêtes de corrélation, nous devons faire savoir à AR ce qu'est un AR. la classe 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)
Quelques points qui méritent d'être clarifiés :
1) models/Post.php
class Post extends CActiveRecord { ...... public function relations() { return array( 'author'=>array(self::BELONGS_TO, 'User', 'author_id'), ); } }
(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'), ); } }
Exemple 2, relation plusieurs-à-plusieurs
dans FailParts.php'Users' => array(self::MANY_MANY, 'User', 'fail_parts_user(fail_parts_id, user_id)'),
Dans User.php
'FailParts' => array(self::MANY_MANY, 'FailParts', 'fail_parts_user(user_id, fail_parts_id)'),
Exemple 3, relation un-à-un
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.
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 >2. Utilisation d'associations multi-tables
Souvent dans les contrôleurs
foreach($posts as $u){ $_tmp_titles[] = $u -> title; } titleStr = implode(', ', $_tmp_titles);
1, chargement retardé
(1) beaucoup -to-one
$author = $post->author;Remarque : l'essence voici en tête-à-tête. (2) Un à plusieurs
$user = User::model()->findByPk(10);
$posts = $user->posts;(3) Plusieurs-à-plusieurs
Il est important de noter que les deux identifiants ont une relation séquentielle. Du point de vue de l'instance $repairInfo, l'association doit être
tandis que du point de vue de $failParts Du point de vue de l'instance, l'association devient
而前面也已经指出,不需要双方都配置,只需需要的一方设置即可。
之前曾使用过的笨方法:
/*方法一:使用表关系(多对多)*/ $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)");
2,主动加载——with
(1)一对多
(2)多对多
$posts = Post::model()->('author')->findAll();
例子:
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)'),
批注:没有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 .")"),
//结论: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是按降序排列
//结论: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)'); ); } }
2,静态查询也支持上面的各种条件查询
如
'doingOutsourceCount' => array(self::STAT, 'Outsource', 'outsource_user(user_id, outsource_id)', 'condition' => "outsource.status_id IN(" . Status::ASSIGNED . "," . Status::STARTED ."," . Status::REJECTED .")"),
其他查询还包括
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次查询,而后者只有一次。两者的选择视情况而定。
相关推荐:
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!