用多对多关联的前提
如果模型 A 多对多关联模型 C,必须存在一张中间表 B 记录着双方的主键,因为就是靠着这张中间表 B 记录着模型 A 与模型 C 的关系。
举例,数据表结构如下
// 商品表
goods
goods_id - integer // 商品主键
goods_name - varchar // 商品名称
// 分类表
category
category_id - integer // 分类主键
name - varchar // 分类名称
// 商品分类关系表
goods_category_rel
id - integer // 主键
goods_id - integer // 商品表主键的外键
category_id - integer // 分类表主键的外键
如果按以前的数据表设计,商品表与分类表不是这样设计的,而是 goods 表有一个 category_id 字段,该字段保存 category 表的 category_id,这样每个商品都对应着一个分类,比如荔枝的分类是水果,但这样的设计缺点也是显而易见的,一个商品只能有一个分类,比如荔枝的分类只能是水果,但如果把数据库设计成上面这样的结构,荔枝的分类就可以有多个,比如除了水果,还能是特价产品,或者是其它分类等等。
商品表模型:
belongsToMany('Category', 'GoodsCategoryRel');
// 完整写法
// return $this->belongsToMany('Category', 'GoodsCategoryRel', 'category_id', 'goods_id');
}
}
belongsToMany
方法的参数如下:
belongsToMany('关联模型', '中间模型', '外键1', '外键2');
_
+关联模型名 (可以指定模型名)_id
_id
中间表模型
分类表模型
shop_goods 表
shop_category 表
shop_goods_category_rel 表
获取 goods_id 为 1 的商品详情以及它的分类
Goods 控制器
Goods 模型
belongsToMany('Category', 'GoodsCategoryRel');
// 完整写法
// return $this->belongsToMany('Category', 'GoodsCategoryRel', 'category_id', 'goods_id');
}
}
Goods 控制器 detail 方法输出
array(7) {
["goods_id"] => int(10001)
["goods_name"] => string(12) "桂味荔枝"
["stock_total"] => int(0)
["status"] => int(10)
["sort"] => int(0)
["is_delete"] => int(0)
["category"] => object(think\Collection)#50 (1) {
["items":protected] => array(2) {
[0] => object(app\api\model\Category)#41 (2) {
["data"] => array(8) {
["category_id"] => int(6)
["name"] => string(12) "新鲜水果"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454738)
["update_time"] => int(1688454738)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#51 (2) {
["data"] => array(5) {
["id"] => int(1001)
["goods_id"] => int(10001)
["category_id"] => int(6)
["create_time"] => int(1688696518)
["update_time"] => int(1688696518)
}
["relation"] => array(0) {
}
}
}
}
[1] => object(app\api\model\Category)#47 (2) {
["data"] => array(8) {
["category_id"] => int(10)
["name"] => string(12) "特价产品"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454870)
["update_time"] => int(1688454870)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#52 (2) {
["data"] => array(5) {
["id"] => int(1002)
["goods_id"] => int(10001)
["category_id"] => int(10)
["create_time"] => int(1688795635)
["update_time"] => int(1688795635)
}
["relation"] => array(0) {
}
}
}
}
}
}
}
关联方法名 category 作为键名,关联查询结果集对象 Collection 作为键值。
获取当前商品的分类,访问 category(关联方法名) 属性即可,如下
category;
halt($categories);
}
}
输出
object(think\Collection)#47 (1) {
["items":protected] => array(2) {
[0] => object(app\api\model\Category)#41 (2) {
["data"] => array(8) {
["category_id"] => int(6)
["name"] => string(12) "新鲜水果"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454738)
["update_time"] => int(1688454738)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#50 (2) {
["data"] => array(5) {
["id"] => int(1001)
["goods_id"] => int(10001)
["category_id"] => int(6)
["create_time"] => int(1688696518)
["update_time"] => int(1688696518)
}
["relation"] => array(0) {
}
}
}
}
[1] => object(app\api\model\Category)#46 (2) {
["data"] => array(8) {
["category_id"] => int(10)
["name"] => string(12) "特价产品"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454870)
["update_time"] => int(1688454870)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#51 (2) {
["data"] => array(5) {
["id"] => int(1002)
["goods_id"] => int(10001)
["category_id"] => int(10)
["create_time"] => int(1688795635)
["update_time"] => int(1688795635)
}
["relation"] => array(0) {
}
}
}
}
}
}
获取所有的商品详情以及它的分类
Goods 控制器
Goods 模型
select();
}
// 多对多获取商品分类
public function category()
{
return $this->belongsToMany('Category', 'GoodsCategoryRel');
// 完整写法
// return $this->belongsToMany('Category', 'GoodsCategoryRel', 'category_id', 'goods_id');
}
}
输出
object(think\Collection)#40 (1) {
["items":protected] => array(1) {
[0] => object(app\api\model\Goods)#42 (2) {
["data"] => array(8) {
["goods_id"] => int(10001)
["goods_name"] => string(12) "桂味荔枝"
["stock_total"] => int(0)
["status"] => int(10)
["sort"] => int(0)
["is_delete"] => int(0)
["create_time"] => int(1688696518)
["update_time"] => int(1688696518)
}
["relation"] => array(1) {
["category"] => object(think\Collection)#50 (1) {
["items":protected] => array(2) {
[0] => object(app\api\model\Category)#41 (2) {
["data"] => array(8) {
["category_id"] => int(6)
["name"] => string(12) "新鲜水果"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454738)
["update_time"] => int(1688454738)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#51 (2) {
["data"] => array(5) {
["id"] => int(1001)
["goods_id"] => int(10001)
["category_id"] => int(6)
["create_time"] => int(1688696518)
["update_time"] => int(1688696518)
}
["relation"] => array(0) {
}
}
}
}
[1] => object(app\api\model\Category)#47 (2) {
["data"] => array(8) {
["category_id"] => int(10)
["name"] => string(12) "特价产品"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454870)
["update_time"] => int(1688454870)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#52 (2) {
["data"] => array(5) {
["id"] => int(1002)
["goods_id"] => int(10001)
["category_id"] => int(10)
["create_time"] => int(1688795635)
["update_time"] => int(1688795635)
}
["relation"] => array(0) {
}
}
}
}
}
}
}
}
}
}
每个商品模型的 relation (关联数组)属性保存着关联模型,关联方法名 category 作为键名,结果集对象作为键值,结果集对象的 items 属性(数组)保存着关联查询结果。
获取每个商品的分类,访问 category(关联方法名) 属性即可,如下
category);
}
}
}
Goods 模型 getList 方法输出
object(think\Collection)#50 (1) {
["items":protected] => array(2) {
[0] => object(app\api\model\Category)#41 (2) {
["data"] => array(8) {
["category_id"] => int(6)
["name"] => string(12) "新鲜水果"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454738)
["update_time"] => int(1688454738)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#51 (2) {
["data"] => array(5) {
["id"] => int(1001)
["goods_id"] => int(10001)
["category_id"] => int(6)
["create_time"] => int(1688696518)
["update_time"] => int(1688696518)
}
["relation"] => array(0) {
}
}
}
}
[1] => object(app\api\model\Category)#47 (2) {
["data"] => array(8) {
["category_id"] => int(10)
["name"] => string(12) "特价产品"
["parent_id"] => int(1)
["image_id"] => int(0)
["status"] => int(1)
["sort"] => int(0)
["create_time"] => int(1688454870)
["update_time"] => int(1688454870)
}
["relation"] => array(1) {
["pivot"] => object(think\model\Pivot)#52 (2) {
["data"] => array(5) {
["id"] => int(1002)
["goods_id"] => int(10001)
["category_id"] => int(10)
["create_time"] => int(1688795635)
["update_time"] => int(1688795635)
}
["relation"] => array(0) {
}
}
}
}
}
}