Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung der YII-bezogenen Abfrage

Detaillierte Erläuterung der YII-bezogenen Abfrage

*文
*文Original
2017-12-28 15:29:041674Durchsuche

Dieser Artikel stellt hauptsächlich die relevanten Informationen zu YII-bezogenen Fragen vor, auf die sich Freunde in Not beziehen können. Ich hoffe, es hilft allen.

1. Konfiguration der Mehrtabellenkorrelation

Bevor wir AR zum Durchführen von Korrelationsabfragen verwenden, müssen wir AR wissen lassen, was ein AR ist Die Klasse hängt mit einer anderen zusammen.

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; , die eine der folgenden vier Konstanten sein kann: self::BELONGS_TO, self::HAS_MANY und self::MANY_MANY; ClassName ist der Name der AR-Klasse, die dieser AR-Klasse zugeordnet ist; ForeignKey gibt den Fremdschlüssel an in der Beziehung verwendet (a oder mehr).

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'), 
); 
} 
}


wo Post und Benutzer Die Beziehung ist eine BELONGS_TO-Beziehung (viele-zu-eins) 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 Benutzer, Die Beziehung zu Post ist eine HAS_MANY-Beziehung (Eins-zu-Viele). 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 mehrere sind Verwenden Sie für Viele-zu-Viele-Beziehungen „Benutzer“ anstelle von „Benutzer“; verwenden Sie „FailParts“ anstelle von „FailPart“.

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, verzögertes Laden

(1) viele -to-one

$post = Post::model()-> ;findByPk(10);
$author = $post->author;

Hinweis: Das Wesentliche 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, dass die beiden IDs eine sequentielle Beziehung haben.

Aus Sicht der $repairInfo-Instanz muss die Zuordnung


'FailParts' => array(self::MANY_MANY, 'FailParts', 'repair_mapping(repair_info_id,fail_parts_id)'),


sein, während aus der Perspektive von $failParts Aus Sicht der Instanz wird die Zuordnung zu


'RepairInfos' => array(self::MANY_MANY, 'RepairInfo', 'repair_mapping(fail_parts_id, repair_info_id)'),


而前面也已经指出,不需要双方都配置,只需需要的一方设置即可。

之前曾使用过的笨方法:


/*方法一:使用表关系(多对多)*/ 
$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次查询,而后者只有一次。两者的选择视情况而定。

相关推荐:

Yii2中的代码自动加载机制

Yii框架中的form表单

Yii2实现增删改查后留在当前页的方法详解

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der YII-bezogenen Abfrage. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn