一對一關聯
版本 | 功能調整 |
---|---|
5.0.5 | 增加關聯自動寫入和刪除 |
5.0.4 | 增加關聯屬性綁定到父模型功能 |
定義
定義一對一關聯,例如,一個用戶都有一個個人資料,我們定義User
模型如下:
namespace appindexmodel;
use thinkModel;
class User extends Model
{
public function profile()
{
return $this->hasOne('Profile');
}
}
hasOne
方法的參數包括:
hasOne('關聯模型名','外鍵名','主鍵名',['模型別名定義'],'join類型');
默認的join
類型為INNER
。
V5.0.3+
版本開始,可以支持為關聯模型定義需要查詢的字段,例如:
namespace appindexmodel;
use thinkModel;
class User extends Model
{
public function profile()
{
return $this->hasOne('Profile')->field('id,name,email');
}
}
如果使用的是
join
方式的關聯,不支持指定field字段。
5.0.5+
版本開始,模型別名定義參數已經廢棄。
關聯查找
定義好關聯之后,就可以使用下面的方法獲取關聯數據:
$user = User::get(1);
// 輸出Profile關聯模型的email屬性
echo $user->profile->email;
如果要根據關聯表的查詢條件查詢當前模型的數據,可以使用hasWhere
方法,例如:
$user = User::hasWhere('profile',['email'=>'thinkphp@qq.com'])->find();
echo $user->name;
默認情況下, 我們使用的是user_id
作為外鍵關聯,如果不是的話則需要在關聯定義的時候指定,例如:
<?php
namespace appindexmodel;
use thinkModel;
class User extends Model
{
public function profile()
{
return $this->hasOne('Profile','uid');
}
}
有一點需要注意的是,關聯方法的命名規范是駝峰法,而關聯屬性則一般是小寫+下劃線的方式,系統在獲取的時候會自動轉換對應,讀取
user_profile
關聯屬性則對應的關聯方法應該是userProfile
。
關聯新增
$user = User::get(1);
// 如果還沒有關聯數據 則進行新增
$user->profile()->save(['email' => 'thinkphp']);
系統會自動把當前模型的主鍵傳入profile模型。
關聯更新
和新增一樣使用save
方法進行更新關聯數據。
$user = User::get(1);
$user->profile->email = 'thinkphp';
$user->profile->save();
// 或者
$user->profile->save(['email' => 'thinkphp']);
定義相對的關聯
我們可以在Profile
模型中定義一個相對的關聯關系,例如:
namespace appindexmodel;
use thinkModel;
class Profile extends Model
{
public function user()
{
return $this->belongsTo('User');
}
}
belongsTo
的參數包括:
belongsTo('關聯模型名','外鍵名','關聯表主鍵名',['模型別名定義'],'join類型');
默認的關聯外鍵是user_id
,如果不是,需要在第二個參數定義
<?php
namespace appindexmodel;
use thinkModel;
class Profile extends Model
{
public function user()
{
return $this->belongsTo('User','uid');
}
}
我們就可以根據檔案資料來獲取用戶模型的信息
$profile = Profile::get(1);
// 輸出User關聯模型的屬性
echo $profile->user->account;
綁定屬性到父模型(V5.0.4+
)
可以在定義關聯的時候使用bind方法綁定屬性到父模型,例如:
<?php
namespace appindexmodel;
use thinkModel;
class User extends Model
{
public function profile()
{
return $this->hasOne('Profile','uid')->bind('nickname,email');
}
}
或者使用數組的方式指定綁定屬性別名
<?php
namespace appindexmodel;
use thinkModel;
class User extends Model
{
public function profile()
{
return $this->hasOne('Profile','uid')->bind([
'email',
'truename' => 'nickname',
'profile_id' => 'id',
]);
}
}
然后使用關聯預載入查詢的時候,可以使用
$user = User::get(1,'profile');
// 輸出Profile關聯模型的email屬性
echo $user->email;
echo $user->profile_id;
綁定關聯屬性不影響原有關聯屬性的讀取,綁定關聯模型的屬性支持讀取器。
如果不是預載入查詢,請使用模型的appendRelationAttr方法追加屬性。
關聯自動寫入(V5.0.5+
)
我們可以使用together
方法更方便的進行關聯自動寫入操作。
寫入
$blog = new Blog;
$blog->name = 'thinkphp';
$blog->title = 'ThinkPHP5關聯實例';
$content = new Content;
$content->data = '實例內容';
$blog->content = $content;
$blog->together('content')->save();
更新
// 查詢
$blog = Blog::get(1);
$blog->title = '更改標題';
$blog->content->data = '更新內容';
// 更新當前模型及關聯模型
$blog->together('content')->save();
刪除
// 查詢
$blog = Blog::get(1);
// 刪除當前及關聯模型
$blog->together('content')->delete();