# 多表關聯
數據表之間經常會互相進行關聯。例如,一篇博客文章可能會有多條評論,或是一張訂單可能對應一個下單客戶。HDPHP模型讓管理和處理這些關聯變得很容易,同時也支持多種類型的關聯。
[TOC]
## 一對一
「一對一」關聯是一個非常基本的關聯關系。舉個例子,一個 User 模型會關聯一個 Phone 模型。為了定義這種關聯關系,我們需要在 User 模型中寫一個 phone 方法。且 phone 方法應該調用 hasOne 方法并返回其結果:
```
namespace system\model;
use houdunwang\model\Model;
class User extends Model{
//獲取與用戶關聯的電話號碼
public function phone()
{
return $this->hasOne(App\Phone::class);
}
}
```
#### 參數說明
模型會假設對應關聯的外鍵名稱是基于模型名稱的。在這個例子里,它會自動假設 Phone 模型擁有 user_id 外鍵。如果你想要重寫這個約定,則可以傳入第二個參數到 hasOne 方法里。
```
return $this->hasOne('App\Phone', 'user_id');
```
此外 Model假設外鍵會和上層模型的 id 字段(或者自定義的 $primaryKey)的值相匹配。換句話說,Model 會尋找用戶的 id 字段與 Phone 模型的 user_id 字段的值相同的紀錄。如果你想讓關聯使用 id 以外的值,則可以傳遞第三個參數至 hasOne 方法來指定你自定義的鍵:
```
return $this->hasOne('App\Phone', 'user_id', 'id');
```
#### 動態屬性
第一個傳到 hasOne 方法里的參數是關聯模型的類名。一旦定義好兩者之間關聯,我們就可以通過使用模型獲取關聯表數據了。
```
$phone = User::find(1)->phone;
```
## 一對多
多對多就是指一第表含有另一張表的多條記錄,比如說一個用戶會有多條新聞。
下面是一對多的定義示例,在用戶模型中定義與新聞的關聯關系。
多對多與一對多一樣,每一個參數是關聯的模型類,第二個參數是foreign_key(文章表中記錄的用戶表的主鍵),第三個參數是local_key(用戶表主鍵)。
```
namespace system\model;
use houdunwang\model\Model;
class User extends Model{
//獲取與用戶關聯的電話號碼
public function news()
{
return $this->hasMany(App\News::class);
}
}
```
比如用戶表的主鍵字段為id,文章表與用戶表關聯字段為user_id,我們可以使用以下形式。
```
$this->hasMany(App\News::class,'user_id','id');
```
#### 參數說明
第三個參數不添加時,系統會自動提取user表主鍵字段
第二個參數不添加時,系統自動使用 “user_+user表主鍵字段” 的形式
#### 動態屬性
以下是使用模型定義的方法的示例。
```
User::find(1)->news;
```
## 一對多(反向關聯)
現在我們已經能訪問到所有用戶的文章,讓我們來接著定義一個通過文章訪問所屬用戶的關聯。若要定義相對于 hasMany 的關聯,可在子級模型定義一個叫做 belongsTo 方法的關聯函數:
```
namespace system\model;
use houdunwang\model\Model;
class News extends Model{
public function user()
{
return $this->belongsTo(App\User::class);
}
}
```
#### 參數說明
belongsTo 可以定義三個參數,第一個參數是關聯的類,第二個參數是文章表中保存用戶表的主鍵字段,第三個參數是用戶表的主鍵字段。
比如用戶表的主鍵字段為id,文章表與用戶表關聯字段為user_id,我們可以使用以下形式。
```
$this->belongsTo(App\User::class,'user_id','id');
```
第三個參數不添加時,系統會自動提取user表主鍵字段
第二個參數不添加時,系統自動使用 “user_+user表主鍵字段” 的形式
#### 動態屬性
一旦關聯被定義之后,則可以通過 user 的「動態屬性」來獲取 News 模型相對應的 User 模型:
```
$news = ModelJoinNews::find(2);
$news->user->username;
```
## 多對多
「多對多」關聯要稍微比 hasOne 及 hasMany 關聯復雜。比如,一個用戶屬于多個用戶組,每個組又可以有多個用戶,這就是多對多關聯。這種情況下我們需要一張中間表來連接這個關聯關系。即三張表,user用戶表 group 用戶組表 user_group中間表。
```
namespace system\model;
use houdunwang\model\Model;
class User extends Model{
public function group()
{
return $this->belongsToMany(ModelJoinGroup::class,'user_group','user_id','group_id');
}
}
```
#### 參數說明
1. 關聯表模型類,以上例來講就是 Group模型
2. 中間表的表名,添加時使用user_group
3. 中間表中保存的當前模型表的主鍵(用戶表主鍵),不添加時使用當前表名_id,以上例來講就是 user_id
4. 中間表中保存的關聯表的主鍵(用戶組表主鍵),不添加時使用關聯表名_id, 以上例來講就是 group_id
#### 關聯使用
```
$user = ModelJoinUser::find(1);
$group = $user->group;
foreach($group as $g){
echo $g->name;
}
```
- 文檔已經遷移到后盾人
- 介紹
- 框架特性
- 開發規范
- 許可協議
- 作者向軍
- 安裝框架
- 更新框架
- 基礎
- 入口文件
- 應用配置
- 優雅鏈接
- 目錄結構
- 系統常量
- 自動加載
- 應用密鑰
- 系統函數
- CSRF保護
- 依賴注入
- 跨域訪問
- 配置
- 配置文件
- 基本功能
- 擴展配置
- c 函數
- 控制器
- 定義聲明
- 基本使用
- 相關函數
- 響應消息
- 路由
- 基礎知識
- 基礎路由
- 路由參數
- 參數檢測
- 依賴注入
- 控制器
- 分組路由
- RESTful
- 別名路由
- 數據
- 配置相關
- 核心操作
- 查詢構造器
- 日志記錄
- 分頁處理
- 事務處理
- 函數相關
- 數據庫
- 數據遷移
- 數據填充
- 模型
- 定義模型
- 模型動作
- 模型驗證
- 自動完成
- 自動過濾
- 字段保護
- 數據填充
- 多表關聯
- 分頁處理
- 倉庫
- 數據倉庫
- 查詢規則
- 視圖
- 基礎知識
- 模板配置
- 模板文件
- 分配數據
- 系統標簽
- 擴展標簽
- 緩存模板
- 模板繼承
- 視圖函數
- widget
- vue組件
- 中間件
- 中間件
- 緩存
- 基本操作
- 文件緩存
- 數據表緩存
- 服務
- 服務容器
- 定制服務
- 相關函數
- 請求
- 基本使用
- 請求擴展
- 測試
- 基礎知識
- 基本使用
- HTTP測試
- 調試
- 調試模式
- 日志管理
- 組件
- 多語言
- 響應處理
- Cookie
- Session
- 驗證碼
- XML
- 自動驗證
- 文件處理
- 壓縮解壓
- RBAC
- 數組增強
- 分頁管理
- 圖像處理
- 生成靜態
- 加密解密
- 字符串
- 數據集合
- 工具服務
- 目錄操作
- 郵件發送
- CURL
- QQ登錄
- 數據備份
- 購物車
- 日志處理
- 命令組件
- 二維碼
- 后盾云
- 日期處理
- 阿里
- 支付寶
- 阿里云直播
- 阿里云短信
- 阿里云郵件
- 阿里云OSS
- SOCKET
- 啟動與關閉
- 前端
- 微信