Heim >Backend-Entwicklung >PHP-Tutorial >Über die Analyse von YII-bezogenen Abfragen
In diesem Artikel werden hauptsächlich die relevanten Informationen zur YII-Korrelationsabfrage vorgestellt
1. Konfiguration der Mehrtabellenkorrelation
Bevor wir AR verwenden, um verwandte Abfragen durchzuführen, müssen wir AR darüber informieren, wie eine AR-Klasse mit einer anderen zusammenhängt.
Die Beziehung zwischen zwei AR-Klassen steht in direktem Zusammenhang mit der Beziehung zwischen den durch die AR-Klassen dargestellten Datentabellen. Aus Datenbanksicht gibt es drei Arten von Beziehungen zwischen den Tabellen A und B: eins-zu-viele (wie tbl_user und tbl_post), eins-zu-eins (wie tbl_user und tbl_profile) und viele-zu-viele ( viele-zu-viele wie tbl_category und tbl_post). In AR gibt es vier Beziehungen:
BELONGS_TO (gehört zu): Wenn die Beziehung zwischen Tabellen A und B eine Eins-zu-Viele-Beziehung ist, gehört Tabelle B zu Tabelle A (Beispiel: Beitrag gehört dem Benutzer). );
HAS_MANY (es gibt mehrere): Wenn die Beziehung zwischen den Tabellen A und B eins zu viele ist, dann hat A mehrere Bs (z. B. hat der Benutzer mehrere Beiträge);
HAS_ONE (es gibt eines): Dies ist ein Sonderfall von HAS_MANY. A kann höchstens ein B haben (zum Beispiel kann Benutzer höchstens ein Profil haben).
MANY_MANY: Dies entspricht den vielen. Zu-viele-Beziehung in der Datenbank. Da die meisten DBMS Viele-zu-Viele-Beziehungen nicht direkt unterstützen, ist eine Beziehungstabelle erforderlich, um die Viele-zu-Viele-Beziehung in eine Eins-zu-Viele-Beziehung aufzuteilen. In unserer Beispieldatenstruktur wird zu diesem Zweck tbl_post_category verwendet. In AR-Begriffen können wir MANY_MANY als die Kombination von BELONGS_TO und HAS_MANY interpretieren. Beispielsweise gehört der Beitrag zu vielen (gehört zu vielen) Kategorien und die Kategorie hat viele (hat viele) Beiträge.
Die in AR definierte Beziehung muss die Relationen()-Methode in CActiveRecord überschreiben. Diese Methode gibt ein Array von Beziehungskonfigurationen zurück. Jedes Array-Element stellt eine einzelne Beziehung im folgenden Format dar.
'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)
wobei VarName der Name der Beziehung ist; RelationType gibt den Beziehungstyp an, der eine der folgenden vier Konstanten sein kann: self::BELONGS_TO, self ::HAS_ONE, self::HAS_MANY und self::MANY_MANY; ClassName ist der Name der AR-Klasse, die dieser AR-Klasse zugeordnet ist; ForeignKey gibt den in der Beziehung verwendeten Fremdschlüssel an (einen oder mehrere).
Ein paar Punkte, die geklärt werden müssen:
(1), worauf bezieht sich VarName? Einzelheiten finden Sie in Beispiel 2 unten.
(2), RelationType. Insgesamt gibt es 4 Typen, nämlich
self::HAS_MANY, self::BELONGS_TO, self::MANY_MANY, self::HAS_ONE.
(3), Klassenname. Das heißt, ein weiteres zugehöriges ../model/classname.php.
(4), ForeignKey. Wer ist der Fremdschlüssel für wen?
(5), zusätzliche Bedingungen
ER-Diagramm
Beispiel 1, Eins-zu-Viele- und Viele-zu-Eins-Beziehung (Beziehung zwischen Beitrag und Benutzer). )
1) models/Post.php
class Post extends CActiveRecord { ...... public function relations() { return array( 'author'=>array(self::BELONGS_TO, 'User', 'author_id'), ); } }
Die Beziehung zwischen Beitrag und Benutzer ist BELONGS_TO (viele zu one) Beziehung und ist über die Autoren-ID des Beitrags mit dem Benutzer verknüpft.
Die Author_ID in Post ist ein Fremdschlüssel und ist dem Benutzer zugeordnet.
Hinweis: VarName ist hier Autor, ein Objekt.
(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'), ); } }
Für den Benutzer gehört die Beziehung zu Post zu HAS_MANY ( Eins-zu-viele-Beziehung. Und über die Autoren-ID des Beitrags mit Post verknüpft.
Beispiel 2, Viele-zu-Viele-Beziehung
in FailParts.php
'Users' => array(self::MANY_MANY, 'User', 'fail_parts_user(fail_parts_id, user_id)'),
In User.php
'FailParts' => array(self::MANY_MANY, 'FailParts', 'fail_parts_user(user_id, fail_parts_id)'),
Da die beiden eine Viele-zu-Viele-Beziehung haben, müssen Benutzer anstelle von FailParts verwendet werden muss anstelle von FailPart verwendet werden.
Die Benutzer und FailParts hier sind der vorherige VarName.
Beispiel 3, Eins-zu-Eins-Beziehung
Es ist relativ einfach und wird vorerst weggelassen.
2, über VarName.
Für Klasse A.php, 'VarName'=>array('RelationType', 'B', 'ForeignKey', ...zusätzliche Optionen)
wobei VarName im Grunde dasselbe ist wie B. Aber nicht unbedingt genau das Gleiche. Zu diesem Zeitpunkt können Sie über VarName in den Ansichten/A/xx.php von A auf B und seine Attributwerte zugreifen.
Wenn es eins-zu-eins ist: A->VarName
Wenn es viele-zu-eins ist: author_name = $post->Author->name;
Wenn ja ist eins-zu-viele: $posts = $author->Post;
Wenn es viele-zu-viele ist: $posts = $author->Post;//Das Wesentliche ist, es in eins aufzuteilen- zu-viele und viele-zu-eins
foreach($posts as $u){ $_tmp_titles[] = $u -> title; } titleStr = implode(', ', $_tmp_titles);
2. Verwendung von Multi-Table-Assoziationen
häufig in Controllern
1, Laden verzögern
(1) Viele-zu-eins
$post = Post::model()->findByPk(10); $author = $post->author;
Hinweis: Die Essenz hier ist eins zu eins.
(2) Eins-zu-viele
$user = User::model()->findByPk(10); $posts = $user->posts;
(3) Viele-zu-viele
Es ist wichtig zu beachten: Es gibt eine sequentielle Beziehung zwischen den beiden IDs .
Aus Sicht der $repairInfo-Instanz muss die Zuordnung
'FailParts' => array(self::MANY_MANY, 'FailParts', 'repair_mapping(repair_info_id,fail_parts_id)'),
sein wird zu For
'RepairInfos' => array(self::MANY_MANY, 'RepairInfo', 'repair_mapping(fail_parts_id, repair_info_id)'),
und wie bereits erwähnt, besteht keine Notwendigkeit, beide Seiten zu konfigurieren, sondern nur die erforderliche Seite kann eingestellt werden.
Dumme Methode, die vorher verwendet wurde:
/*方法一:使用表关系(多对多)*/ $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, aktives Laden - mit
(1 ) Eins-zu-viele
(2) Viele-zu-viele
$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次查询,而后者只有一次。两者的选择视情况而定。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
如何实现Yii2框架中使用PHPExcel导出Excel文件
Das obige ist der detaillierte Inhalt vonÜber die Analyse von YII-bezogenen Abfragen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!