CakePHP 3,Model 的資料庫關聯...

edited 十月 2013 in CakePHP
這裡寫的挺亂的~
建議可以直接看英文的這份:http://manual.cakephp.org/chapter/6
以及 Screencasts:http://cakephp.org/pages/screencasts


CakePHP 的 model 物件中,已經包好了很多很多東西,不過我想對於初期開始寫 CakePHP 的人會跟我一樣,對於 model 中的 hasOne , hasMany, belongsTo , hasAndBelongsToMany 有著一些困惑,但是當搞清楚後,確會惑然開朗的愛上他們。

我們先從關聯式資料庫資料庫說起吧~

資料庫正規化大概看這文章的人有一半以上應該都聽過,也有實際的經驗。
在正規化後,資料會被切割程很多不同的資料表。

這些資料表都利用對方或是自己的 primary key 互相做到關聯,如此才能找到 a 然後跟著找到 b 跟 c ...

但是這在我們以前寫程式的時候,可能就需要寫很多次SQL, 或是採用 join 的方式去在資料庫關聯多個資料表取得資料。

而這麼多個資料表,本身彼此則會利用對方的 id 作為一種關聯的 key ...
這樣說可能很模糊,我們下面就講講 cakephp 的 model 來看看吧。

那在 CakePHP 的 model 則是用 hasOne , hasMany, belongsTo , hasAndBelongsToMany 來達到這些目的。

hasOne:別人那有一比資料有 key 對應到我的 id
hasMany:別人那有很多個比資料有 key 對應到我的 id
belongsTo : 我這有一個 key是對應到別人的 id
hasAndBelongsToMany:在別的資料表中有很多個 key 對應到我的 id ,且有另外一個在別人那的 key 對應到另外一個人的id

上面聽起來好像很複雜吧....

我們用 CakePHP.org 的範例來看看吧:
假設現在資料庫有3個表格:
users{
primary key : id
}
profiles{
primary key : id
link to users: user_id
}
comments{
primarykey : id
link to users: user_id
}

我們要建立 user -> profile 的關係
在 user 物件中 hasOne 的用法
代碼:
<?php
class User extends AppModel
{
var $name = 'User';
var $hasOne = array('Profile' => // 對方物件的名稱
array('className' => 'Profile', // 對方物件的名稱
'conditions' => '',
'order' => '',
'dependent' => true, // 當 true 則會進行同步刪除
'foreignKey' => 'user_id' // foreign key
)
);
}
?>

這樣的話他的在尋找資料的時候輸出就會變成這樣
代碼:
$user = $this->User->findById('25');
print_r($user);

//output:

Array
(
[User] => Array
(
[id] => 25
[first_name] => John
[last_name] => Anderson
[username] => psychic
[pasword] => c4k3roxx
)

[Profile] => Array
(
[id] => 4
[name] => Cool Blue
[header_color] => aquamarine
[user_id] = 25
)
)

你會發現,我們只叫 user 去找一下 id = 25 的資料,但是他會聰明的把有關連的資料也一起找出來給你。

那若是在 Profile 的設定呢? 他能不能反過來找 user
代碼:
<?php
class Profile extends AppModel
{
var $name = 'Profile';
var $belongsTo = array('User' =>
array('className' => 'User',
'conditions' => '',
'order' => '',
'foreignKey' => 'user_id'
)
);
}
?>

$profile = $this->Profile->findById('4');
print_r($profile);

//output:

Array
(

[Profile] => Array
(
[id] => 4
[name] => Cool Blue
[header_color] => aquamarine
[user_id] = 25
)

[User] => Array
(
[id] => 25
[first_name] => John
[last_name] => Anderson
[username] => psychic
[pasword] => c4k3roxx
)
)


哇!~原來 belongsTo 就是可以讓他自動找回去....

但是上面這兩種情況都是對方只有一筆的情況,若是很多筆呢?
像是一篇文章有很多人回應要怎麼辦?

那我們就來看看 hasMany 吧
代碼:
<?php
class User extends AppModel
{
var $name = 'User';
var $hasMany = array('Comment' =>
array('className' => 'Comment',
'conditions' => 'Comment.moderated = 1',
'order' => 'Comment.created DESC',
'limit' => '5',
'foreignKey' => 'user_id',
'dependent' => true,
'exclusive' => false,
'finderSql' => ''
)
);

// Here's the hasOne relationship we defined earlier...
var $hasOne = array('Profile' =>
array('className' => 'Profile',
'conditions' => '',
'order' => '',
'dependent' => true,
'foreignKey' => 'user_id'
)
);
}
?>
$user = $this->User->findById('25');
print_r($user);

//output:

Array
(
[User] => Array
(
[id] => 25
[first_name] => John
[last_name] => Anderson
[username] => psychic
[pasword] => c4k3roxx
)

[Profile] => Array
(
[id] => 4
[name] => Cool Blue
[header_color] => aquamarine
[user_id] = 25
)

[Comment] => Array
(
[0] => Array
(
[id] => 247
[user_id] => 25
[body] => The hasMany assocation is nice to have.
)

[1] => Array
(
[id] => 256
[user_id] => 25
[body] => The hasMany assocation is really nice to have.
)

[2] => Array
(
[id] => 269
[user_id] => 25
[body] => The hasMany assocation is really, really nice to have.
)

[3] => Array
(
[id] => 285
[user_id] => 25
[body] => The hasMany assocation is extremely nice to have.
)

[4] => Array
(
[id] => 286
[user_id] => 25
[body] => The hasMany assocation is super nice to have.
)

)
)


哎呀!,沒想到吧,只要設定好 hasMany ...當我在找 user 的時候,他也會自動找出跟他相關的 comments 唷!~

原始討論: http://twpug.net/x/modules/newbb/viewtopic.php?topic_id=1597

評論

Sign In or Register to comment.