举杯邀月

thinkphp6.0 模型一对多关联,模型关联取出的数据再关联另一个模型

摘要:在实际开发中经常遇到一些复杂得数据库表得关联设计,可能需要好几层得关联才能得到我们最终想要得数据。在thinkphp中,这种情况可以通过模型关联来实现,用极少得代码完成数据得关联,极大得节约了开发时间。

在实际开发中经常遇到一些复杂得数据库表得关联设计,可能需要好几层得关联才能得到我们最终想要得数据。在thinkphp中,这种情况可以通过模型关联来实现,用极少得代码完成数据得关联,极大得节约了开发时间。

一个产品(product表)有多个属性(product_attr表),然后要用关联得属性ID去属性表(attr表)查询对应得属性名称。

插一句题外话,可能有的同学要问了,为甚不直接把属性名称存到产品属性表(product_attr表),查询就不用关联查询了。因为如果我们直接把属性名称写在产品属性表里,如果属性名发生变更就需要去把所有得数据更新一遍,这样得数据库设计在某些情况下是不合理得。

数据库

product表

product_id product_name
1 产品1
2 产品2

product_attr表

id product_id attr_id
1 1 1
2 1 2
3 2 3
4 2 4

attr表

attr_id attr_name
1 属性1
2 属性2
3 属性3
4 属性4

模型

为演示功能使用,只展示必要代码

Product.php

class Product
{

    /**
     * @description: 关联属性
     * @author: injurys
     */
    public function attr()
    {
        return $this->hasMany(ProductAttr::class, 'product_id', 'product_id');
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13

ProductAttr.php

class ProductAttr
{

    /**
     * @description: 关联属性名称
     * @author: injurys
     */
    public function name()
    {
        return $this->belongsTo(Attr::class, 'attr_id', 'attr_id');
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13

hasMany 、belongsTo 方法的参数为:(‘关联模型类名’, ‘外键’, ‘主键’);

查询程序

 Product::with(['attr', 'attr.name'])
    ->order('product_id', 'desc')
    ->paginate([
        'page' => 1,
        'list_rows' => 20
    ])->each(function (&$item)  {
        $item->attr->each(function (&$val) {
            $val = $val->toArray();
            $val['name'] = isset($val['name']['attr_name']) ? $val['name']['attr_name'] : '';
            return $val;
        });
    })->toArray();
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12

hasWhere关联条件

Product::hasWhere('attr', function ($query) use ($where) {
        $query->where($where);
    })->with(['attr.name'])
    ->order('product_id', 'desc')
    ->paginate([
        'page' => 1,
        'list_rows' => 20
    ])->each(function (&$item)  {
        $item->attr->each(function (&$val) {
            $val = $val->toArray();
            $val['name'] = isset($val['name']['attr_name']) ? $val['name']['attr_name'] : '';
            return $val;
        });
    })->toArray();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14

这样就可以把关联的数据查询出来了。

作者:举杯邀月

出处: http://www.hug-code.cn/archives/5fd9c0dab3ca3.html

2020-10-17 标签: thinkphpphp