laravel關(guān)聯(lián)模型中的多對多關(guān)系解析-belongsToMany

laravel-china手冊

場景

員工表通過 員工與任務(wù)的關(guān)聯(lián)表 獲取到自己的所有任務(wù)

數(shù)據(jù)表

員工表-employee    employee_id
任務(wù)表- task task_id
員工與任務(wù)的關(guān)聯(lián)表  task_target   
task_target_id-自增ID
target_type-參與任務(wù)的類型,員工或者門店團(tuán)隊
target_id-參與對象的ID

那么,在員工的模型中,應(yīng)該這樣寫關(guān)聯(lián)關(guān)系

 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

其實這種語句就是通過一個中間表中,與另一個表的關(guān)聯(lián)字段task_id獲取到另一個表的數(shù)據(jù)。對了,其中 where 條件,其實就是第三個參數(shù)target_id值對應(yīng)的中間表的數(shù)據(jù)。

belongsToMany參數(shù)解析

參數(shù)(Task::class)1:是最終要獲取數(shù)據(jù)的表模型
參數(shù)(task_target)2:是與本表與第一個參數(shù)表的關(guān)聯(lián)表
參數(shù)(target_id)3:此參數(shù)是foreignPivotKey,是中間表task_target針對本表的外鍵
參數(shù)(task_id)4:是relatedPivotKey。related 其實是指Task::class表。所以字段其實是中間表task_target針對Task表的外鍵。
參數(shù)(employee_id)5:是parentKey。這個是 where 條件中的字段值
wherePivot 是中間表 task_target 的條件

擴(kuò)展

pivot:是樞紐的意思,其實是指兩個表的中間關(guān)聯(lián)表
外鍵:外鍵是在本表里面。其實就是本表與另一個表關(guān)聯(lián)的字段,通過外鍵的這個字段,可以獲取到另一個表的數(shù)據(jù)。

一對多關(guān)聯(lián)解析

belongsTo 的第二個參數(shù)是本表的外鍵
第三個參數(shù)是關(guān)聯(lián)表的,元本表外鍵關(guān)聯(lián)的字段
最終結(jié)果其實是where 條件中
第三個參數(shù)是 字段,第二個參數(shù)是已知的值

但是 hasOne 則不同
hasOne 的最終結(jié)果是
第二個字段是鍵字段,第三個參數(shù)是已知的值
image.png
image.png
select * from `org_employee` where `org_employee`.`employee_id` = ?  limit 1

其實取的值是 where org_employee.ownerKey=foreignKey,foreignKey是本表中的已知值??汕f不能把這兩個參數(shù)單純的理解成外鍵和本件。如果ownerKey換成本表的主鍵,則會報錯,org_employee表沒有本表主鍵這個字段

之所以我們按照手冊上的操作不需要區(qū)分本地主鍵和外鍵是因為,比如一個用戶參與了很多評論

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
參數(shù)值是3,所以得到了用戶數(shù)據(jù)
因為這種關(guān)系,所以不會報錯。但其實這個ID 是與user.id 想對應(yīng)的,并不是本地的主鍵
如果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 就是關(guān)聯(lián)的表
$ownerKey = $ownerKey ?: $instance->getKeyName(); 就是關(guān)聯(lián)表的ID

hasOne 和 belongsTo 是不一樣的

employee 表主鍵改成 employee_id11
record 表還是 employee_id   而且沒有 employee_id11 字段
hasOne

第三個字段是 where 條件中的值,第二個字段是where 條件中的鍵
其實外鍵此處就是關(guān)聯(lián)表的鍵(注意,不一定是主鍵)
localKey 其實就是本表的值

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,602評論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,441評論 6 13
  • 優(yōu)化之電量篇 優(yōu)化之渲染篇 優(yōu)化之內(nèi)存篇 優(yōu)化之運算篇 這幾篇都十分精美,圖碼兼并,理解方便。上乘。
    alucardzhou閱讀 327評論 0 2
  • 墓碑 文 /陌宇軒 從時光的角度上看 你有著為人民的一面 為思念的故人留一方靜土 你忍心聽 世人呼喚親友的哭聲 你...
    小哲小詩閱讀 174評論 0 0
  • 什么是UI-Router? AngularJS 是一種富客戶端單頁面應(yīng)用框架,所以要在一個頁面呈現(xiàn)不同的視圖,路由...
    belllee閱讀 700評論 0 1

友情鏈接更多精彩內(nèi)容