在实际开发中经常遇到一些复杂得数据库表得关联设计,可能需要好几层得关联才能得到我们最终想要得数据。在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');
}
}
ProductAttr.php
class ProductAttr
{
/**
* @description: 关联属性名称
* @author: injurys
*/
public function name()
{
return $this->belongsTo(Attr::class, 'attr_id', 'attr_id');
}
}
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();
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();
这样就可以把关联的数据查询出来了。
友情提示:垃圾评论一律封号...