数据表之间是纵横交叉、相互关联的拉威尔的一对一,一对多比较好理解,官网介绍滴很详细了,在此我就不赘述啦,重点我记下多对多的关系
一种常见的关联关系是多对多,即表A的某条记录通过中间表C与表B的多条记录关联,反之亦然。比如一个用户有多种角色,反之一个角色对应多个用户。
为了测试该关联关系,我们沿用官网的用户角色示例:
需要三张数据表:用户、角色和角色_用户,角色_用户表按照关联模型名的字母顺序命名(这里角色_用户是中间表),并且包含用户编号和角色编号两个列。
多对多关联通过编写返回下面是一个例子方法返回结果的方法来定义。废话不说多,直接上数据结构:
1:创建一个角色表角色,并添加一些初始化数据:
设置外键检查=0;- -用户的表结构- -如果存在"用户",则删除表;CREATE TABLE ` users `(` id ' int(10)无符号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,` memory _ token ' varchar(100)COLLATE utf8 _ unicode _ ci DEFAULT NULL,` created _ at ` timestamp NOT NULL DEFAULT ' 000-0033333333-用户记录-插入"用户"值(' 1 ',' admin ','[emailprotected]',' $2y$10$J/yXqscucanrHAGZp9G6.Tu1Md .SOljX3M8WrHsUdrgat4zeSuhC ',' ilocxtjzjwhrmidlg 1 ckoygcwqckuyx1pyaoluzippcqft 5 SS7 lbci 7i ',' 2016-04-21 16:263:23 ',' 2016-12-14 09:29:59 ');INSERT INTO ' user ' VALUES(' 2 ',' baidu ','[emailprotected]',' $ 2y $ 10 $ 2 a5zj4 pnj 5 UCP 1 dn3n x . 5 uj/ap7p 6o 4 NP 2 ba a55 afra 8/rti1k 6 I 2 ',null,' 2016-04-22 06:48336010 ',' 2016-04-22 06:483333:10 'INSERT INTO ' users ' VALUES(' 3 ',' fantasy ','[emailprotected]','',null,' 2017-06-14 10:38:57 ',' 2017-06-15 10:39:01 ');2:创建一个角色表角色,并添加一些初始化数据:
设置外键检查=0;- -角色的表结构- -如果存在"角色",则删除表;CREATE TABLE `roles` (`id` int(10)无符号NOT NULL AUTO_INCREMENT,` name ` varchar(255)COLLATE utf8 _ unicode _ ci NOT NULL,` created _ at ` timestamp NOT NULL DEFAULT ' 0000-00-00:00,` updated _ at ` timestamp NOT NULL DEFAULT ' 0000-00-00:00 ',主键(` id `) ENGINE=inno-角色记录- -插入"角色"值('1',)超级版主', '2016-04-21 16:26:23', '2016-12-14 09:29:59');插入"角色"值('2',"司令', '2016-04-22 06:48:10', '2016-04-22 06:48:10');插入"角色"值('3',"军长', '2017-06-14 10:38:57', '2017-06-15 10:39:01');插入"角色"值('4',"司长', '2017-06-07 10:41:41', '2017-06-15 10:41:51');插入"角色"值('5',"团战', '2017-06-22 10:41:44', '2017-06-28 10:41:54');插入"角色"值('6',"小兵', '2017-06-22 10:41:47', '2017-06-22 10:41:56');3:创建一个中间表角色_用户用于记录用户表与角色表的对应关系,并添加一些初始化数据:
设置外键检查=0;role_user的表结构- -如果存在“role _ user ”,则删除表;CREATE TABLE ` role _ user `(` id ' int(10)无符号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=Latin 1;role _ user的记录--INSERT INTO ` role _ user ` VALUES(' 1 ',' 1 ',' 2 ',' 2017-06-07 11:42:13 ',' 2017-06-21 113:32336016 ');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 ');注意我们在定义中间表的时候没有在末尾加s,命名规则是按字母顺序的,把角色放在前面,用户放在后面,用_,把它们分开,都是为了适应雄辩模型关联的默认设置:如果在定义多对多关联的时候没有指定中间表,雄辩默认中间表是用这个规则拼接的。
创建角色模型:
?phpnamespace App Models使用照明数据库雄辩模型;/* * * class role * @ package app models * @ mixin eloquet */class role扩展模型{}然后我们在User模型上定义roles方法:
?phpnamespace App Models使用照明数据库雄辩模型;/* * * }}注意:如上所述,如果中间表不是role_user,则需要作为第二个参数传入belongsToMany方法。如果中间表中的字段不是user_id和role_id,让我们在这里将它们命名为$user_id和$role_id,那么它需要作为第三个参数传递到这个方法中。$role_id作为第四个参数传递到方法中。如果相关方的合法名称不是角色,那么相关方的相应合法名称也可以作为第五个参数传递到方法中。
接下来,我们在控制器中编写测试代码:
?PHP $ user=user : find(1);$ roles=$ user-roles;echo“用户”拥有的角色。$用户名。':';foreach($roles as $role)回显$role-name。' ';//对应的输出是:用户所拥有的角色admin:指挥官、指挥官、团,当然像所有其他关联类型一样,可以调用roles方法给关联查询添加约束:
user : find(1)-roles()-order by(' name ')-get();如前所述,为了确定关联连接表的表名,雄辩按照字母顺序连接两个关联模型的名称。但是,您可以通过将第二个参数传递给belongsToMany方法来重写此约定——:
返回$ this-belongsToMany(' App Models Role ',' user _ roles ');除了自定义连接表的表名,您还可以通过向belongsToMany方法传递附加参数来自定义表中字段的列名。第三个参数是您定义的关联模型的外键名,第四个参数是您要连接的模型的外键名:
返回$ this-belongsToMany(' App Models Role ',' user_roles ',' user_id ',' Role _ id ');定义相对关系
要定义与多对多关联相反的关联关系,只需在关联模型中调用belongsToMany方法。我们在角色模型中定义了用户方法:
?phpnamespace App Models使用照明数据库雄辩模型;/* * * }}如您所见,定义的关系与其对应的用户中定义的关系完全相同,只是前者指的是AppModelsRole,后者指的是AppModelsUser。因为我们再次使用了belongsToMany方法,所以在定义具有多对多关系的关系时,所有公共表和键定制选项都是可用的。
测试代码如下:
$ role=role :3360 find(2);$ users=$ role-users;echo“角色#”下的用户。$角色名。':';foreach($ user as $ user)回显$user-name。' ';//对应的输出是:角色#下的用户指挥官:admin幻想百度如你所见,处理多对多关联需要一个中间表。雄辩提供了一些有用的方法来与这个中间表进行交互。例如,我们假设用户对象有许多关联的角色对象。在访问这些关联之后,我们可以使用这些模型上的pivot属性来访问中间表字段:
$ roles=user : find(1)-roles;foreach($ roles as $ role)echo $ role-pivot-role _ id。br ';//对应的输出是:2 3 5。请注意,我们得到的每个角色模型都被自动分配了透视属性。该属性包含一个表示中间表的模型,可以像其他雄辩模型一样使用。
默认情况下,只能在透视对象上使用模型主键。如果数据透视表包含附加属性,则必须在定义关联关系时指定这些属性:
返回$ this-belongsToMany(' App Models Role ')-with pivot(' column 1 ',' column 2 ');例如,我们修改role_user表并添加一个字段用户名数据,如下所示:
修改模型用户:
?phpnamespace App Models使用照明数据库雄辩模型;/* * *返回$ this-belongsToMany(' App Models Role ')-with pivot(' username ');}}测试代码如下:
$ user=user : find(1);foreach($ user-roles as $ role)echo $ role-pivot-username;//对应的输出是:matt matt 2 matt 3。如果希望数据透视表自动包含created_at和updated_at时间戳,请在定义关系时使用withTimestamps方法:
返回$ this-belongsToMany(' App Models Role ')-with timestamp();通过中间的表字段过滤关联关系
定义关系时,还可以使用wherePivot和wherePivotIn方法来筛选belongsToMany返回的结果集:
返回$ this-belongstoany(' app models role ')-带pivot ('username ')-其中pivot(' username ',' matt 2 ');//返回$ this-belongsToMany(' App Models Role ')-where pivotin(' Role _ id ',[1,2]);测试代码如下:
$ user=user : find(1);print _ r($ user-roles-to array());以上对应的输出:
Array([0]=Array([id]=3[name]=commander[created _ at]=2017-06-14 10:38336057[updated _ at]=2017-06-15 10:39336001[=Array([user _ id]=1[role _ id]=3[username]=matt 2)))如果希望数据透视表自动包含created _ at和updated _ at时间戳,请使用
返回$ this-belongsToMany(' App Models Role ')-with timestamp();以上是边肖介绍的PHP laravel中多对多关系例子的详细说明,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!