轉載自:http://blog.csdn.net/wyodyia/article/details/5846053
下面我們以一個(gè)實(shí)例來(lái)講述關(guān)聯(lián)操作的簡(jiǎn)單用法,由于關(guān)聯(lián)操作定義復雜,這里只是講述一般的情況。我們以用戶(hù)表為核心,來(lái)描述如何使用表的關(guān)聯(lián)操作。假設存在如下的關(guān)聯(lián)情況:
每個(gè)用戶(hù)有一個(gè)檔案表是HAS_ONE關(guān)聯(lián);
每個(gè)用戶(hù)屬于一個(gè)部門(mén)是BELONGS_TO關(guān)聯(lián);
每個(gè)用戶(hù)有多張銀行卡是HAS_MANY關(guān)聯(lián);
每個(gè)用戶(hù)可能屬于多個(gè)項目組,每個(gè)項目組也有多個(gè)用戶(hù)是MANY_TO_MANY關(guān)聯(lián)。
我們首先來(lái)創(chuàng )建數據表,以MySQL為例:
// 部門(mén)表
CREATE TABLE `think_dept` (
`id` smallint(3) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 用戶(hù)表
CREATE TABLE `think_user` (
`id` mediumint(6) NOT NULL auto_increment,
`name` varchar(25) NOT NULL,
`dept_id` smallint(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 用戶(hù)檔案表
CREATE TABLE `think_profile` (
`id` mediumint(6) NOT NULL auto_increment,
`user_id` mediumint(6) NOT NULL,
`email` varchar(255) NOT NULL,
`nickname` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 銀行卡表
CREATE TABLE `think_card` (
`id` mediumint(6) NOT NULL auto_increment,
`user_id` mediumint(6) NOT NULL,
`card` varchar(25) character set latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 項目組表
CREATE TABLE `think_group` (
`id` mediumint(6) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 用戶(hù)-項目組表
CREATE TABLE `think_user_group` (
`id` mediumint(6) NOT NULL auto_increment,
`group_id` mediumint(5) NOT NULL,
`user_id` mediumint(5) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
下面我們分別來(lái)給數據表定義對應的模型,這里關(guān)鍵是用戶(hù)模型的定義,因為我們以用戶(hù)表為核心來(lái)定義和使用關(guān)聯(lián),所以其他模型中無(wú)需再定義關(guān)聯(lián)關(guān)系。
class UserModel extends Model
{
protected $_link = array(
‘Profile’=>HAS_ONE,
‘Dept’=>BELONGS_TO,
‘Card’=>HAS_MANY,
‘Group’=>MANY_TO_MANY,
);
}
上面的關(guān)聯(lián)定義,我們采用了最簡(jiǎn)潔的定義方式,也就是所有規則都按照系統的默認規則進(jìn)行。這些規則包括主鍵、外鍵、表名的規范。完整的關(guān)聯(lián)定義可以寫(xiě)成:
class UserModel extends Model
{
protected $_link = array(
‘Profile’=>array(
‘mapping_type’=>HAS_ONE,
‘mapping_name’=>’Profile’,
‘class_name’=>’Profile’,
‘foreign_key’=>’user_id’,
),
‘Dept’=> array(
‘mapping_type’=> BELONGS_TO,
‘mapping_name’=>’Dept’,
‘class_name’=>’Dept’,
‘foreign_key’=>’dept_id’,
),
‘Card’=> array(
‘mapping_type’=> HAS_MANY,
‘mapping_name’=>’Card’,
‘class_name’=>’Card’,
‘foreign_key’=>’user_id’,
),
‘Group’=> array(
‘mapping_type’=> MANY_TO_MANY,
‘mapping_name’=>’Group’,
‘class_name’=>’Group’,
‘foreign_key’=>’user_id’,
‘relation_foreign_key’=>’group_id’,
‘relation_table’=>’think_user_group’,
),
);
}
如果要給關(guān)聯(lián)定義增加可選的屬性,則必須采用完整定義的方式。
其中Profile Dept Card Group 分別是其他幾個(gè)模型的名稱(chēng),定義如下:
class ProfileModel extends Model {}
class DeptModel extends Model {}
class CardModel extends Model {}
class GroupModel extends Model {}
因為我們以用戶(hù)表為核心來(lái)讀取關(guān)聯(lián),所以用戶(hù)和項目組的中間表 默認的規則必須是 user_group
也就是我們上面創(chuàng )建的think_user_group表,如果你的中間表的名稱(chēng)不是這個(gè)規則,需要定義relation_table屬性。
為了演示的方便,我們首先給部門(mén)表和項目組表增加一些數據:
INSERT INTO `think_dept` (`id`, `name`) VALUES (1, ‘開(kāi)發(fā)部’),(2, ‘銷(xiāo)售部’) ,(3, ‘財務(wù)部’);
INSERT INTO `think_group` (`id`, `name`) VALUES (1, ‘項目組1′),(2, ‘項目組2′) ,(3, ‘項目組3′);
接下來(lái)首先演示關(guān)聯(lián)寫(xiě)入,我們創(chuàng )建一個(gè)IndexAction用于演示操作,記得在項目配置文件里面定義好數據庫的連接信息。
在IndexAction的index操作方法里面添加
$User = D(”User”);
$User->name = ‘thinkphp’;
$User->dept_id = 1;
$User->Profile = array(
‘email’ =>’liu21st@gmail.com’,
‘nickname’ =>’流年’,
);
$User->Card = array(
array(‘id’=>1.’card’=>’12345678′),
array(‘id’=>2,’card’=>’88888888′),
);
$User->Group = array(
array(’id’=>1),
array(’id’=>2),
);
$User->add(”,true);
在執行User模型的add方法的同時(shí),我們已經(jīng)寫(xiě)入了think_profile、think_card和think_user_group三個(gè)表的數據,BELONGS_TO關(guān)聯(lián)關(guān)系是不會(huì )自動(dòng)寫(xiě)入的。
如果我們在模型里面設置了autoAddRelations屬性為T(mén)rue的話(huà),使用
$User->add();
方法即可同時(shí)進(jìn)行關(guān)聯(lián)寫(xiě)入。
為了驗證關(guān)聯(lián)數據是否已經(jīng)寫(xiě)入,我們現在來(lái)使用關(guān)聯(lián)查詢(xún)把相關(guān)的數據查出來(lái)。
$user = $User->relation(true)->find(1);
Dump($user);
可以看到輸出的結果,把User模型關(guān)聯(lián)的數據都顯示出來(lái)了。如果我們只希望獲取某個(gè)關(guān)聯(lián)數據,可以使用
$user = $User->relation(‘Profile’)->find(1);
表示只是獲取關(guān)聯(lián)的用戶(hù)檔案數據。
數據集的查詢(xún)也可以支持關(guān)聯(lián)查詢(xún),使用
$user = $User->relation(true)->findAll();
能夠顯示出完整的含有關(guān)聯(lián)數據的數據集。
我們再來(lái)更新關(guān)聯(lián)數據
$user[‘id’] = 1;
$user['name'] = ‘tp’;
$user['Profile']['email'] = ‘thinkphp@qq.com’;
$user['Card'] = array(
array(’id’=>1,’card’=>’66666666′),
array(’id’=>2,’card’=>’77777777′),
);
$user[‘Group’] = array(
array(’id’=>1),
array(’id’=>3),
);
$User->save($user,’id=1′,true);
注意關(guān)聯(lián)更新的時(shí)候一定要包含主鍵數據。
關(guān)聯(lián)刪除
$User->deleteById(2,true);
聯(lián)系客服