轉(zhuǎn)載自:http://blog.csdn.net/wyodyia/article/details/5846053
下面我們以一個(gè)實(shí)例來講述關(guān)聯(lián)操作的簡單用法,由于關(guān)聯(lián)操作定義復(fù)雜,這里只是講述一般的情況。我們以用戶表為核心,來描述如何使用表的關(guān)聯(lián)操作。假設(shè)存在如下的關(guān)聯(lián)情況:
每個(gè)用戶有一個(gè)檔案表是HAS_ONE關(guān)聯(lián);
每個(gè)用戶屬于一個(gè)部門是BELONGS_TO關(guān)聯(lián);
每個(gè)用戶有多張銀行卡是HAS_MANY關(guān)聯(lián);
每個(gè)用戶可能屬于多個(gè)項(xiàng)目組,每個(gè)項(xiàng)目組也有多個(gè)用戶是MANY_TO_MANY關(guān)聯(lián)。
我們首先來創(chuàng)建數(shù)據(jù)表,以MySQL為例:
// 部門表
CREATE TABLE `think_dept` (
`id` smallint(3) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 用戶表
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 ;
// 用戶檔案表
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 ;
// 項(xiàng)目組表
CREATE TABLE `think_group` (
`id` mediumint(6) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
// 用戶-項(xiàng)目組表
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;
下面我們分別來給數(shù)據(jù)表定義對應(yīng)的模型,這里關(guān)鍵是用戶模型的定義,因?yàn)槲覀円杂脩舯頌楹诵膩矶x和使用關(guān)聯(lián),所以其他模型中無需再定義關(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)定義,我們采用了最簡潔的定義方式,也就是所有規(guī)則都按照系統(tǒng)的默認(rèn)規(guī)則進(jìn)行。這些規(guī)則包括主鍵、外鍵、表名的規(guī)范。完整的關(guān)聯(lián)定義可以寫成:
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è)模型的名稱,定義如下:
class ProfileModel extends Model {}
class DeptModel extends Model {}
class CardModel extends Model {}
class GroupModel extends Model {}
因?yàn)槲覀円杂脩舯頌楹诵膩碜x取關(guān)聯(lián),所以用戶和項(xiàng)目組的中間表 默認(rèn)的規(guī)則必須是 user_group
也就是我們上面創(chuàng)建的think_user_group表,如果你的中間表的名稱不是這個(gè)規(guī)則,需要定義relation_table屬性。
為了演示的方便,我們首先給部門表和項(xiàng)目組表增加一些數(shù)據(jù):
INSERT INTO `think_dept` (`id`, `name`) VALUES (1, ‘開發(fā)部’),(2, ‘銷售部’) ,(3, ‘財(cái)務(wù)部’);
INSERT INTO `think_group` (`id`, `name`) VALUES (1, ‘項(xiàng)目組1′),(2, ‘項(xiàng)目組2′) ,(3, ‘項(xiàng)目組3′);
接下來首先演示關(guān)聯(lián)寫入,我們創(chuàng)建一個(gè)IndexAction用于演示操作,記得在項(xiàng)目配置文件里面定義好數(shù)據(jù)庫的連接信息。
在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);
在執(zhí)行User模型的add方法的同時(shí),我們已經(jīng)寫入了think_profile、think_card和think_user_group三個(gè)表的數(shù)據(jù),BELONGS_TO關(guān)聯(lián)關(guān)系是不會自動寫入的。
如果我們在模型里面設(shè)置了autoAddRelations屬性為True的話,使用
$User->add();
方法即可同時(shí)進(jìn)行關(guān)聯(lián)寫入。
為了驗(yàn)證關(guān)聯(lián)數(shù)據(jù)是否已經(jīng)寫入,我們現(xiàn)在來使用關(guān)聯(lián)查詢把相關(guān)的數(shù)據(jù)查出來。
$user = $User->relation(true)->find(1);
Dump($user);
可以看到輸出的結(jié)果,把User模型關(guān)聯(lián)的數(shù)據(jù)都顯示出來了。如果我們只希望獲取某個(gè)關(guān)聯(lián)數(shù)據(jù),可以使用
$user = $User->relation(‘Profile’)->find(1);
表示只是獲取關(guān)聯(lián)的用戶檔案數(shù)據(jù)。
數(shù)據(jù)集的查詢也可以支持關(guān)聯(lián)查詢,使用
$user = $User->relation(true)->findAll();
能夠顯示出完整的含有關(guān)聯(lián)數(shù)據(jù)的數(shù)據(jù)集。
我們再來更新關(guān)聯(lián)數(shù)據(jù)
$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í)候一定要包含主鍵數(shù)據(jù)。
關(guān)聯(lián)刪除
$User->deleteById(2,true);