美文网首页laravel核心
laravel关联模型中的多对多关系解析-belongsToMa

laravel关联模型中的多对多关系解析-belongsToMa

作者: 云龙789 | 来源:发表于2018-09-21 11:59 被阅读72次

laravel-china手册

场景

员工表通过 员工与任务的关联表 获取到自己的所有任务

数据表

员工表-employee    employee_id
任务表- task task_id
员工与任务的关联表  task_target   
task_target_id-自增ID
target_type-参与任务的类型,员工或者门店团队
target_id-参与对象的ID

那么,在员工的模型中,应该这样写关联关系

 public function hasManyTask()
    {
        return $this->belongsToMany(Task::class,'task_target','target_id','task_id','employee_id')
            ->wherePivot('target_type','=',Target::TARGET_TYPE_EMPLOYEE);
    }

解析原 SQL 
select `task`.*, 
`task_target`.`target_id` as `pivot_target_id`, 
`task_target`.`task_id` as `pivot_task_id` 
from `task`
inner join `task_target` on `task`.`task_id` = `task_target`.`task_id` 
where `task_target`.`target_id` = 1513 
and `task_target`.`target_type` = 1 and `task`.`deleted_at` is null
image.png

其实这种语句就是通过一个中间表中,与另一个表的关联字段task_id获取到另一个表的数据。对了,其中 where 条件,其实就是第三个参数target_id值对应的中间表的数据。

belongsToMany参数解析

参数(Task::class)1:是最终要获取数据的表模型
参数(task_target)2:是与本表与第一个参数表的关联表
参数(target_id)3:此参数是foreignPivotKey,是中间表task_target针对本表的外键
参数(task_id)4:是relatedPivotKey。related 其实是指Task::class表。所以字段其实是中间表task_target针对Task表的外键。
参数(employee_id)5:是parentKey。这个是 where 条件中的字段值
wherePivot 是中间表 task_target 的条件

扩展

pivot:是枢纽的意思,其实是指两个表的中间关联表
外键:外键是在本表里面。其实就是本表与另一个表关联的字段,通过外键的这个字段,可以获取到另一个表的数据。

一对多关联解析

belongsTo 的第二个参数是本表的外键
第三个参数是关联表的,元本表外键关联的字段
最终结果其实是where 条件中
第三个参数是 字段,第二个参数是已知的值

但是 hasOne 则不同
hasOne 的最终结果是
第二个字段是键字段,第三个参数是已知的值
image.png image.png
select * from `org_employee` where `org_employee`.`employee_id` = ?  limit 1

其实取的值是 where org_employee.ownerKey=foreignKey,foreignKey是本表中的已知值。可千万不能把这两个参数单纯的理解成外键和本件。如果ownerKey换成本表的主键,则会报错,org_employee表没有本表主键这个字段

之所以我们按照手册上的操作不需要区分本地主键和外键是因为,比如一个用户参与了很多评论

user --id
post --- id ,user_id
比如  user.id=3
post.id=2,post.user_id=3
那么在评论中获取用户的SQL语句其实会是
public function user()
{
    return belongsTo(User::class,'user_id','id');
}
select * from user where user.id=? limit 1
参数值是3,所以得到了用户数据
因为这种关系,所以不会报错。但其实这个ID 是与user.id 想对应的,并不是本地的主键
如果user.id 改成 user.abc   则
return belongsTo(User::class,'user_id','abc');
select * from user where user.abc=? limit 1
post表里面根本不需要这个表
image.png
image.png

通过源码我们知道 $instance 就是关联的表
$ownerKey = $ownerKey ?: $instance->getKeyName(); 就是关联表的ID

hasOne 和 belongsTo 是不一样的

employee 表主键改成 employee_id11
record 表还是 employee_id   而且没有 employee_id11 字段
hasOne

第三个字段是 where 条件中的值,第二个字段是where 条件中的键
其实外键此处就是关联表的键(注意,不一定是主键)
localKey 其实就是本表的值

相关文章

网友评论

    本文标题:laravel关联模型中的多对多关系解析-belongsToMa

    本文链接:https://www.haomeiwen.com/subject/fysanftx.html