Yii 多表關聯relations

//在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的一個字段。php

顯然,doingOutsources是真實數據表Outsource的別名,因此在condition中可使用doingOutsources.status_id,固然也可使用Outsource.status_id。另本表名user的默認別名是t。sql

1,首先多表關聯是在models/xx.php的relations裏配置的。並且是互配,但有區別。數據庫

格式:yii

?post

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

須要弄清楚的幾點:this

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

2,RelationType。一共有4種,分別爲self::HAS_MANY, self::BELONGS_TO, self::MANY_MANY, self::HAS_ONE。日誌

3,ClassName。即關聯的另外一個../model/類名.php。code

4,ForeignKey。誰是誰的外鍵?寫了是用主鍵關聯,爲空兩個表不是用主鍵關聯須要on對象

5,附加條件

兩個表不是用主鍵關聯

?

1
2
'user'     =>      array     (self::BELONGS_TO,      'OaskUser'         ''     ,     'on'     =>     'name=userName'         'select'     =>     'TrueName'     ),
'varchar'     =>     array     (self::HAS_ONE,      'CustomerEntityVarchar'         'entity_id'     ,     'select'     =>     'varchar.value'     ,     'on'     =>     'varchar.attribute_id="831"'     ),

BELONGS_TO(屬於): 若是表 A 和 B 之間的關係是一對多,則 表 B 屬於 表 A ;

HAS_MANY(有多個): 若是表 A 和 B 之間的關係是一對多,則 A 有多個 B ;

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

MANY_MANY: 這個對應於數據庫中的多對多關係。 因爲多數 DBMS 不直接支持 多對多 關係,所以須要有一個關聯表將多對多關係分割爲一對多關係。在 AR術語中,咱們能夠解釋 MANY_MANY 爲 BELONGS_TO 和 HAS_MANY 的組合。

STAT:除了上述的關係類型,一個特殊的關係,稱爲STAT也支持可用於進行統計查詢(或聚合查詢)。 檢索聚合對相關對象的信息,如數量。如 一篇日誌共有多少個評論

?

1
'detailCounts'     =>      array     (self::STAT,      'PurchaseDetail'         'purchase_hid'     ),

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

(1)models/Post.php

?

1
2
3
4
5
6
7
8
9
10
11
12
class     Post      extends     CActiveRecord 
         ...... 
         public     function     relations() 
        
             return     array    
                 'author'     =>     array     (self::BELONGS_TO,      'User'         'author_id'     ), 
                 'categories'     =>     array     (self::MANY_MANY,      'Category'    
                     'tbl_post_category(post_id, category_id)'     ), 
             ); 
        
}

其中Post與User的關係是BELONGS_TO(多對一)關係,並經過Post的author_id與User關聯。Post中author_id是外鍵,關聯到User中。注:此處的VarName是author,一個對象。

(2)models/User.php

?

1
2
3
4
5
6
7
8
9
10
class     User      extends     CActiveRecord 
         ...... 
         public     function     relations() 
        
             return     array    
                 'posts'     =>     array     (self::HAS_MANY,      'Post'         'author_id'     ), 
             ); 
        
}

對於User,與Post的關係是屬於HAS_MANY(一對多)關係。並經過Post的author_id與Post關聯。 因爲二者是一對多關係,因此要用posts

例2,多對多關係。中間表名(本表外鍵,many表外鍵)

在FailParts.php中

?

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

在User.php中

?

1
'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

若是是一對多:A->VarName->name

若是是多對多:

?

1
2
3
4
5
$users     = As->VarName 
foreach     (     $users     as     $u     ){ 
        $_tmp_users     [] =      $u     -> getName; 
userStr = implode(     ', '         $_tmp_users     );

懶惰式加載(lazy loading,也可譯爲 遲加載) 方式

?

1
2
3
4
// 獲取 ID 爲 10 的帖子 
$post     =Post::model()->findByPk(10); 
// 獲取帖子的做者(author): 此處將執行一個關聯查詢。 
$author     =     $post     ->author;

懶惰式加載用起來很方便,但在某些狀況下並不高效。

渴求式加載(eager loading)方式。

?

1
$posts     =Post::model()->with(     'author'     ,     'categories'     )->findAll();

AR scopes

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//SchoolDepartment::model()->allDepartmentAndClass($id)->findAll(); 
public     function     relations() { 
         return     array    
             'class'     =>      array     (self::HAS_MANY,      'SchoolClass'         'school_department_id'     ), 
         ); 
   
public     function     scopes() { 
         return     array    
             'allDepartmentAndClass'    
         ); 
   
public     function     allDepartmentAndClass(     $id     ) { 
         $this     ->getDbCriteria()->mergeWith(     array    
             'with'     =>      "class"    
             'condition'     =>      "t.tbl_school_id=$id"    
         )); 
         return     $this    
}

yii的relations裏self::BELONGS_TO默認是用當前指定的鍵跟關聯表的主鍵進行join,例如:

Post

?

1
2
3
return     array     (
         'reply'     =>      array     (self::BELONGS_TO,      'BookPostReply'         'postid'     ),
);

默認生成的sql相似 on id = postid,id是本表的主鍵,postid是表BookPostReply的一個字段(主鍵)

可是須要生成 on BookPostReply.postid = t.postid

關聯非主鍵字段

方法一,改爲以下:

?

1
2
3
return     array     (
         'reply'     =>      array     (self::BELONGS_TO,      'BookPostReply'         ''         'on'     =>      'postid=postid'     ),
);

方法二:

?

1
array     (self::BELONGS_TO,     '對應的模型'     ,     array     (     '本模型的外鍵'     =>     '對應模型的主鍵'     ))

這樣也能夠定義的,只要明確指定主鍵和對應表的外鍵就能夠了。

官方開發指南里是這樣寫的:

?

1
array     (     'fkc1'     =>     'pkc1'     ,     'fkc2'     =>     'pkc2'     )

描述:yii的relations 關聯非主鍵字段

相關文章
相關標籤/搜索