搜尋
首頁後端開發php教程關於YII關聯查詢的解析

關於YII關聯查詢的解析

Jun 15, 2018 pm 01:51 PM
yii關聯查詢

這篇文章主要介紹了YII關聯查詢的相關資料,需要的朋友可以參考下

一、多表關聯的配置

在我們使用AR 執行關聯查詢之前,我們需要讓AR 知道一個AR 類別是怎麼關聯到另一個的。

兩個 AR 類別之間的關係直接透過 AR 類別所代表的資料表之間的關係相關聯。從資料庫的角度來說,表A 和B 之間有三種關係:一對多(one-to-many,例如tbl_user 和tbl_post),一對一( one-to-one 例如tbl_user 和tbl_profile)和多對多(many-to-many 例如tbl_category 和tbl_post)。在AR 中,有四種關係:

BELONGS_TO(屬於): 如果表A 和B 之間的關係是一對多,則表B 屬於表A (例如Post 屬於User);

HAS_MANY(有多個): 如果表A 和B 之間的關係是一對多,則A 有多個B (例如User 有多個Post);

HAS_ONE(有一個) : 這是HAS_MANY 的一個特例,A 最多有一個B (例如User 最多有一個Profile);

MANY_MANY: 這個對應於資料庫中的多對多關係。由於多數 DBMS 不直接支援 多對多 關係,因此需要有一個關聯表將 多對多 關係分割為 一對多 關係。在我們的範例資料結構中,tbl_post_category 就是用於此目的的。在 AR 術語中,我們可以解釋MANY_MANY 為 BELONGS_TO 和 HAS_MANY 的組合。例如,Post 屬於多個(belongs to many) Category ,Category 有多個(has many) Post.

AR 中定義關係需要覆蓋 CActiveRecord 中的 relations() 方法。此方法傳回一個關係配置陣列。每個數組元素透過如下格式表示單一的關係。

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

其中VarName 是關係的名字;RelationType 指定關係類型,可以是一下四個常數之一: self::BELONGS_TO, self::HAS_ONE, self::HAS_MANY and self::MANY_MANY;ClassName 是此AR 類別所關聯的AR 類別的名字; ForeignKey 指定關係中使用的外鍵(一個或多個)。

需要弄清楚的幾點:

(1),VarName指什麼?詳見下面例2。

(2),RelationType。共有4種,分別為

self::HAS_MANY, self::BELONGS_TO, self::MANY_MANY, self::HAS_ONE。

(3),ClassName。即關聯的另一個../model/類別名稱.php。

(4),ForeignKey。誰是誰的外鍵?

(5),附加條件

ER Diagram

#例1,一對多與多對一關係(post和user之間的關係)

1)models/Post.php

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

其中Post與User的關係是BELONGS_TO(多對一)關係,並透過Post的author_id與User關聯。

Post中author_id是外鍵,關聯到User中。

註:此處的VarName是author,一個物件。

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

對於User,與Post的關係是屬於HAS_MANY(一對多)關係。並透過Post的author_id與Post關聯。

範例2,多對多重關係

在FailParts.php中

'Users' => array(self::MANY_MANY, 'User', 'fail_parts_user(fail_parts_id, user_id)'),

在User.php中

'FailParts' => array(self::MANY_MANY, 'FailParts', 'fail_parts_user(user_id, fail_parts_id)'),

#因為兩者是多對多關係,所以要用Users,而不是User;要用FailParts ,而不是FailPart。

此處的Users和FailParts,即為前面的VarName。

範例3,一對一關係

比較簡​​單,暫略。

2,關於VarName。

對於類別A.php,'VarName'=>array('RelationType', 'B', 'ForeignKey', ...additional options)
其中VarName與B基本相同。但未必完全一樣。此時就可以在A的views/A/xx.php中透過VarName來存取B及其屬性值了。

如果是一對一:A->VarName
如果是多對一:author_name = $post->Author->name;
如果一對多:$posts = $author->Post;
如果是多對多:$posts = $author->Post;//本質是拆成一對多對一

foreach($posts as $u){ 
$_tmp_titles[] = $u -> title; 
} 
titleStr = implode(', ', $_tmp_titles);

二、多表關聯的使用

#常常在controllers裡

1,延遲載入

(1)多對一

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

批註:此處本質是一對一。

(2)一對多

$user = User::model()->findByPk(10); 
$posts = $user->posts;

(3)多對多

#需要重點注意:兩個id有先後關係。

站在$repairInfo實例的角度,關聯關係必須是

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

而站在$failParts實例的角度,則關聯關係變為

'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次查询,而后者只有一次。两者的选择视情况而定。

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

相关推荐:

Yii中表单用法实例

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

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

以上是關於YII關聯查詢的解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
超越炒作:評估當今PHP的角色超越炒作:評估當今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

PHP中的弱參考是什麼?什麼時候有用?PHP中的弱參考是什麼?什麼時候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

解釋PHP中的__ Invoke Magic方法。解釋PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。

解釋PHP 8.1中的纖維以進行並發。解釋PHP 8.1中的纖維以進行並發。Apr 12, 2025 am 12:05 AM

Fibers在PHP8.1中引入,提升了並發處理能力。 1)Fibers是一種輕量級的並發模型,類似於協程。 2)它們允許開發者手動控制任務的執行流,適合處理I/O密集型任務。 3)使用Fibers可以編寫更高效、響應性更強的代碼。

PHP社區:資源,支持和發展PHP社區:資源,支持和發展Apr 12, 2025 am 12:04 AM

PHP社區提供了豐富的資源和支持,幫助開發者成長。 1)資源包括官方文檔、教程、博客和開源項目如Laravel和Symfony。 2)支持可以通過StackOverflow、Reddit和Slack頻道獲得。 3)開發動態可以通過關注RFC了解。 4)融入社區可以通過積極參與、貢獻代碼和學習分享來實現。

PHP與Python:了解差異PHP與Python:了解差異Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

php:死亡還是簡單地適應?php:死亡還是簡單地適應?Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來:改編和創新PHP的未來:改編和創新Apr 11, 2025 am 12:01 AM

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器