日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

laravel中的多对多关系详解

發(fā)布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 laravel中的多对多关系详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一種常見的關(guān)聯(lián)關(guān)系是多對多,即表A的某條記錄通過中間表C與表B的多條記錄關(guān)聯(lián),反之亦然。比如一個用戶有多種角色,反之一個角色對應(yīng)多個用戶。為了測試該關(guān)聯(lián)關(guān)系,我們沿用官網(wǎng)的用戶角色示例:

需要三張數(shù)據(jù)表:users、roles?和?role_user,role_user?表按照關(guān)聯(lián)模型名的字母順序命名(這里role_user是中間表),并且包含?user_id?和?role_id兩個列。

多對多關(guān)聯(lián)通過編寫返回?belongsToMany?方法返回結(jié)果的方法來定義。廢話不說多,直接上數(shù)據(jù)結(jié)構(gòu):

1:創(chuàng)建一個角色表roles,并添加一些初始化數(shù)據(jù):

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'admin', 'admin@163.com', '$2y$10$J/yXqscucanrHAGZp9G6..Tu1Md.SOljX3M8WrHsUdrgat4zeSuhC', 'ilocXtjZJwhrmIdLG1cKOYegeCwQCkuyx1pYAOLuzY2PpScQFT5Ss7lBCi7i', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `users` VALUES ('2', 'baidu', '10940370@qq.com', '$2y$10$2A5zJ4pnJ5uCp1DN3NX.5uj/Ap7P6O4nP2BaA55aFra8/rti1K6I2', null, '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `users` VALUES ('3', 'fantasy', '1009@qq.com', '', null, '2017-06-14 10:38:57', '2017-06-15 10:39:01');

2:創(chuàng)建一個角色表roles,并添加一些初始化數(shù)據(jù):

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for roles
-- ----------------------------
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- ----------------------------
-- Records of roles
-- ----------------------------
INSERT INTO `roles` VALUES ('1', '超級版主', '2016-04-21 16:26:23', '2016-12-14 09:29:59');
INSERT INTO `roles` VALUES ('2', '司令', '2016-04-22 06:48:10', '2016-04-22 06:48:10');
INSERT INTO `roles` VALUES ('3', '軍長', '2017-06-14 10:38:57', '2017-06-15 10:39:01');
INSERT INTO `roles` VALUES ('4', '司長', '2017-06-07 10:41:41', '2017-06-15 10:41:51');
INSERT INTO `roles` VALUES ('5', '團(tuán)戰(zhàn)', '2017-06-22 10:41:44', '2017-06-28 10:41:54');
INSERT INTO `roles` VALUES ('6', '小兵', '2017-06-22 10:41:47', '2017-06-22 10:41:56');

3:創(chuàng)建一個中間表role_user用于記錄users表與roles表的對應(yīng)關(guān)系,并添加一些初始化數(shù)據(jù):

SET FOREIGN_KEY_CHECKS=0;-- ---------------------------- -- Table structure for role_user -- ---------------------------- DROP TABLE IF EXISTS `role_user`; CREATE TABLE `role_user` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`user_id` int(11) DEFAULT NULL,`role_id` int(11) DEFAULT NULL,`created_at` datetime DEFAULT NULL,`updated_at` datetime DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;-- ---------------------------- -- Records of role_user -- ---------------------------- INSERT INTO `role_user` VALUES ('1', '1', '2', '2017-06-07 11:42:13', '2017-06-21 11:32:16'); INSERT INTO `role_user` VALUES ('2', '1', '3', '2017-06-07 11:32:13', '2017-06-07 11:22:13'); INSERT INTO `role_user` VALUES ('3', '2', '4', '2017-06-07 11:32:13', '2017-06-07 11:12:13'); INSERT INTO `role_user` VALUES ('4', '1', '5', '2017-06-07 11:32:13', '2017-06-07 11:22:13'); INSERT INTO `role_user` VALUES ('5', '3', '6', '2017-06-07 11:32:13', '2017-06-07 11:52:13'); INSERT INTO `role_user` VALUES ('6', '3', '2', '2017-06-07 11:32:13', '2017-06-07 11:42:13'); INSERT INTO `role_user` VALUES ('7', '2', '2', '2017-06-07 11:42:13', '2017-06-07 11:52:13');

注意我們定義中間表的時候沒有在結(jié)尾加s并且命名規(guī)則是按照字母表順序,將role放在前面,user放在后面,并且用_分隔,這一切都是為了適應(yīng)Eloquent模型關(guān)聯(lián)的默認(rèn)設(shè)置:在定義多對多關(guān)聯(lián)的時候如果沒有指定中間表,Eloquent默認(rèn)的中間表使用這種規(guī)則拼接出來。

創(chuàng)建一個Role模型:

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;/*** Class Role* @package App\Models* @mixin \Eloquent*/ class Role extends Model {}

然后我們在?User?模型上定義?roles?方法:

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;/*** Class User* @package App\Models* @mixin \Eloquent*/ class User extends Model {/*** 用戶角色*/public function roles(){return $this->belongsToMany('App\Models\Role');} }

注:正如我們上面提到的,如果中間表不是role_user,那么需要將中間表作為第二個參數(shù)傳入belongsToMany方法,如果中間表中的字段不是user_id和role_id,這里我們姑且將其命名為$user_id和$role_id,那么需要將$user_id作為第三個參數(shù)傳入該方法,$role_id作為第四個參數(shù)傳入該方法,如果關(guān)聯(lián)方法名不是roles還可以將對應(yīng)的關(guān)聯(lián)方法名作為第五個參數(shù)傳入該方法。

接下來我們在控制器中編寫測試代碼:

<?php
$user = User::find(1); $roles = $user->roles; echo '用戶'.$user->name.'所擁有的角色:'; foreach($roles as $role)echo $role->name.' '; //對應(yīng)輸出為:用戶admin所擁有的角色:司令 ?軍長 ?團(tuán)戰(zhàn) ?

?當(dāng)然,和所有其它關(guān)聯(lián)關(guān)系類型一樣,你可以調(diào)用roles?方法來添加條件約束到關(guān)聯(lián)查詢上:

User::find(1)->roles()->orderBy('name')->get();

正如前面所提到的,為了確定關(guān)聯(lián)關(guān)系連接表的表名,Eloquent 以字母順序連接兩個關(guān)聯(lián)模型的名字。不過,你可以重寫這種約定 —— 通過傳遞第二個參數(shù)到?belongsToMany?方法:

return $this->belongsToMany('App\Models\Role', 'user_roles');

除了自定義連接表的表名,你還可以通過傳遞額外參數(shù)到?belongsToMany?方法來自定義該表中字段的列名。第三個參數(shù)是你定義關(guān)聯(lián)關(guān)系模型的外鍵名稱,第四個參數(shù)你要連接到的模型的外鍵名稱:

return $this->belongsToMany('App\Models\Role', 'user_roles', 'user_id', 'role_id');

定義相對的關(guān)聯(lián)關(guān)系

要定義與多對多關(guān)聯(lián)相對的關(guān)聯(lián)關(guān)系,只需在關(guān)聯(lián)模型中調(diào)用一下?belongsToMany?方法即可。我們在?Role?模型中定義?users?方法:

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;/*** Class Role* @package App\Models* @mixin \Eloquent*/ class Role extends Model {/*** 角色用戶*/public function users(){return $this->belongsToMany('App\Models\User');}}

?正如你所看到的,定義的關(guān)聯(lián)關(guān)系和與其對應(yīng)的User?中定義的一模一樣,只是前者引用?App\Models\Role,后者引用App\Models\User,由于我們再次使用了?belongsToMany?方法,所有的常用表和鍵自定義選項在定義與多對多相對的關(guān)聯(lián)關(guān)系時都是可用的。

測試代碼如下:

$role = Role::find(2); $users = $role->users; echo '角色#'.$role->name.'下面的用戶:'; foreach ($users as $user) echo $user->name.' ';//對應(yīng)輸出為:角色#司令下面的用戶:admin fantasy baidu?

正如你看到的,處理多對多關(guān)聯(lián)要求一個中間表。Eloquent 提供了一些有用的方法來與這個中間表進(jìn)行交互,例如,我們假設(shè)?User?對象有很多與之關(guān)聯(lián)的?Role?對象,訪問這些關(guān)聯(lián)關(guān)系之后,我們可以使用這些模型上的pivot?屬性訪問中間表字段:

$roles = User::find(1)->roles; foreach ($roles as $role) echo $role->pivot->role_id.'<br>';//對應(yīng)輸出為:2 3 5

?注意我們獲取到的每一個?Role?模型都被自動賦上了?pivot?屬性。該屬性包含一個代表中間表的模型,并且可以像其它 Eloquent 模型一樣使用。

默認(rèn)情況下,只有模型主鍵才能用在?pivot?對象上,如果你的?pivot?表包含額外的屬性,必須在定義關(guān)聯(lián)關(guān)系時進(jìn)行指定:

return $this->belongsToMany('App\Models\Role')->withPivot('column1', 'column2');

比如我們修改role_user表增加一個字段 username 數(shù)據(jù)如下:

修改模型User:

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;/*** Class User* @package App\Models* @mixin \Eloquent*/ class User extends Model {/*** 用戶角色*/public function roles(){//return $this->belongsToMany('App\Models\Role');return $this->belongsToMany('App\Models\Role')->withPivot('username');} }

?測試代碼如下:

$user = User::find(1); foreach ($user->roles as $role) echo $role->pivot->username;//對應(yīng)輸出為:馬特馬特2馬特3

如果你想要你的?pivot?表自動包含created_at?和?updated_at?時間戳,在關(guān)聯(lián)關(guān)系定義時使用?withTimestamps?方法:

return $this->belongsToMany('App\Models\Role')->withTimestamps();

?通過中間表字段過濾關(guān)聯(lián)關(guān)系

你還可以在定義關(guān)聯(lián)關(guān)系的時候使用?wherePivot?和?wherePivotIn?方法過濾belongsToMany?返回的結(jié)果集:

return $this->belongsToMany('App\Models\Role')->withPivot('username')->wherePivot('username', '馬特2'); //return $this->belongsToMany('App\Models\Role')->wherePivotIn('role_id', [1, 2]);

測試代碼如下:

$user = User::find(1); print_r($user->roles->toArray());

以上對應(yīng)輸出:

Array ([0] => Array([id] => 3[name] => 軍長[created_at] => 2017-06-14 10:38:57[updated_at] => 2017-06-15 10:39:01[pivot] => Array([user_id] => 1[role_id] => 3[username] => 馬特2)))

如果你想要你的pivot表自動包含created_at和updated_at時間戳,在關(guān)聯(lián)關(guān)系定義時使用withTimestamps方法:

return $this->belongsToMany('App\Models\Role')->withTimestamps();

?http://www.cnblogs.com/phpper/p/6950557.html(轉(zhuǎn)載地址)

轉(zhuǎn)載于:https://www.cnblogs.com/seven-ahz/p/7533433.html

總結(jié)

以上是生活随笔為你收集整理的laravel中的多对多关系详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。