Heim  >  Artikel  >  Backend-Entwicklung  >  Über die Analyse von YII-bezogenen Abfragen

Über die Analyse von YII-bezogenen Abfragen

不言
不言Original
2018-06-15 13:51:371274Durchsuche

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中文网!

相关推荐:

Yii中表单用法实例

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

如何实现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!

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