關聯定義
多對多關聯不像一對一和一對多關聯,它還要多建一個中間表用來處理多對多的關聯,例如:
#城市 create table city ( c_id int primary key AUTO_INCREMENT comment "編號", c_name varchar(255) comment '城市名稱' ) #區域(別名) create table area ( a_id int primary key AUTO_INCREMENT comment "編號", a_name varchar(255) comment '區域名稱' ) #中間表(樞紐表) create table city_area ( id int primary key AUTO_INCREMENT comment "編號", aid int comment '區域外鍵', cid int comment '城市外鍵' )
一個區域(別名)有多座城市,一座城市有多個區域(別名),例如:廣州即屬於一線城市,也是珠三角地區,同時它還叫“羊城”;而珠三角地區包括的城市有廣州、佛山、肇慶、深圳、東莞、惠州等。
下面使用belongsToMany關聯中間表,city(城市)模型:
<?php namespace app\demo\model; use think\Model; class City extends Model //城市表 { public function area(){ //belongsToMany('區域模型','中間表名','外鍵名','外鍵名'); return $this->belongsToMany('Area','city_area','aid','cid'); } }
注:belongsToMany后面兩個一定要對應中間表外鍵的順序

area(區域)模型:
<?php namespace app\demo\model; use think\Model; class Area extends Model //全國區域表 { public function city(){ //belongsToMany('城市模型','中間表名','外鍵名','外鍵名'); return $this->belongsToMany("Area",'city_area','aid','cid'); } }
中間表模型可以不需要建立
關聯查詢
我們可以通過下面的方式獲取關聯數據
$city = City::get(1); foreach($city->area as $role){ // 獲取城市id為1的所有區域名稱 dump($role->a_name); }
如果要獲取中間表數據,可以使用
$city = City::get(1); foreach($city->area as $role){ // 獲取中間表數據 print_r($role->pivot); }
關聯新增
//關聯單條新增 $city = City::get(1); //增加關聯數據 會自動寫入中間表數據 $city->area()->save(['a_name'=>'珠三角地區']); //批量新增 $city->area()->saveAll([ ['a_name'=>'一線城市'], ['a_name'=>'羊城'], ]);
只新增中間表數據,可以使用
//方法一:添加中間表數據 $city = City::get(1); //條件查詢,找出珠三角地區 $area = Area::getByAName("珠三角地區"); //使用attach方法增加中間表的數據 $city->area()->attach($area);//新增數據:城市的id為1,區域為珠三角地區的id*/ //方法二:,效果等同方法一 $city = City::get(1); $city->area()->attach(2);//新增數據:城市的id為1,區域為2
下面是新增中間表方法二執行的SQL語句:
INSERT INTO `city_area` (`cid` , `aid`) VALUES (1 , 2)
關聯刪除
只刪除中間表數據,但不刪關聯模型的數據
//方法一: $city = City::get(1); $area = Area::getByAName("珠三角地區"); //關聯刪除數據,但不刪關聯模型的數據 $city->area()->detach($area); //方法二 $city = City::get(1); //DELETE FROM `city_area` WHERE `cid` = 1 AND `aid` = 1 $city->area()->detach(1); //批量刪除 $city->area()->detach([1]);
刪除中間表方法二執行的SQL:
DELETE FROM `city_area` WHERE `cid` = 1 AND `aid` = 1
如果有必要,也可以刪除中間表的數據同時刪除關聯模型
$city = City::get(1); $area = Area::getByAName("羊城"); //這里不光刪除中間表,也刪除羊城 $city->area()->detach($area,true);
