[TOC]
#### 關聯定義
我們以用戶和檔案的一對一關聯為例,在User模型類中添加關聯定義方法,然后在方法中調用hasOne方法即可:
~~~
<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
// 開啟自動寫入時間戳
protected $autoWriteTimestamp = true;
// 定義自動完成的屬性
protected $insert = ['status' => 1];
// 定義關聯方法
public function profile()
{
// 用戶HAS ONE檔案關聯
return $this->hasOne('Profile');
}
}
~~~
hasOne方法有5個參數,依次分別是:
~~~
hasOne('關聯模型名','關聯外鍵','主鍵','別名定義','join類型')
~~~
默認的外鍵是:當前模型名_id,主鍵則是自動獲取,如果你的表設計符合這一規范的話,只需要設置關聯的模型名即可.
通常關聯模型和當前模型都是相同的命名空間,如果關聯模型在不同的命名空間,需要指定完整的類名,例如:
~~~
// 關聯admin模塊下面的模型對象
return $this->hasOne('\app\admin\Profile');
~~~
要進行模型的關聯操作,我們必須同時定義好關聯模型,Profile模型定義如下:
~~~
<?php
namespace app\index\model;
use think\Model;
class Profile extends Model
{
protected $type = [
'birthday' => 'timestamp:Y-m-d',
];
}
~~~
可以看到Profile模型中并沒有定義關聯方法。如果你的關聯操作都是基于User模型的話,Profile模型中并不需要定義關聯方法。
如果你需要基于Profile模型來進行關聯操作,則需要在Profile模型中定義對應的BELONGS_TO關聯,如下:
~~~
<?php
namespace app\index\model;
use think\Model;
class Profile extends Model
{
protected $type = [
'birthday' => 'timestamp:Y-m-d',
];
public function user()
{
// 檔案 BELONGS TO 關聯用戶
return $this->belongsTo('User');
}
}
~~~
belongsTo方法和hasOne一樣,也有5個參數:
~~~
belongsTo('關聯模型名','關聯外鍵','關聯模型主鍵','別名定義','join類型')
~~~
#### 關聯寫入
首先來看下如何進行關聯數據的寫入,創建User控制器的add操作方法如下:
~~~
<?php
namespace app\index\controller;
use app\index\model\Profile;
use app\index\model\User as UserModel;
class User
{
// 關聯新增數據
public function add()
{
$user = new UserModel;
$user->name = 'thinkphp';
$user->password = '123456';
$user->nickname = '流年';
if ($user->save()) {
// 寫入關聯數據
$profile = new Profile;
$profile->truename = '劉晨';
$profile->birthday = '1977-03-05';
$profile->address = '中國上海';
$profile->email = 'thinkphp@qq.com';
$user->profile()->save($profile);
return '用戶新增成功';
} else {
return $user->getError();
}
}
}
~~~
關聯模型的寫入調用了關聯方法profile(),該方法返回的是一個Relation對象,執行save方法會自動傳入當前模型User的主鍵作為關聯鍵值,所以不需要手動傳入Profile模型的user_id屬性。
save方法也可以直接使用數組而不是Profile對象,例如:
~~~
<?php
namespace app\index\controller;
use app\index\model\Profile;
use app\index\model\User as UserModel;
class User
{
// 關聯新增數據
public function add()
{
$user = new UserModel;
$user->name = 'thinkphp';
$user->password = '123456';
$user->nickname = '流年';
if ($user->save()) {
// 寫入關聯數據
$profile['truename'] = '劉晨';
$profile['birthday'] = '1977-03-05';
$profile['address'] = '中國上海';
$profile['email'] = 'thinkphp@qq.com';
$user->profile()->save($profile);
return '用戶[ ' . $user->name . ' ]新增成功';
} else {
return $user->getError();
}
}
}
~~~
#### 關聯查詢
~~~
一對一的關聯查詢很簡單,直接把關聯對象當成屬性來用即可,例如:
public function read($id)
{
$user = UserModel::get($id);
echo $user->name . '<br/>';
echo $user->nickname . '<br/>';
echo $user->profile->truename . '<br/>';
echo $user->profile->email . '<br/>';
}
~~~
以上關聯查詢的時候,只有在獲取關聯對象($user->profile)的時候才會進行實際的關聯查詢,缺點是會可能進行多次查詢,但可以使用預載入查詢來提高查詢性能,對于一對一關聯來說,只需要進行一次查詢即可獲取關聯對象數據,例如:
~~~
public function read($id)
{
$user = UserModel::get($id,'profile');
echo $user->name . '<br/>';
echo $user->nickname . '<br/>';
echo $user->profile->truename . '<br/>';
echo $user->profile->email . '<br/>';
}
~~~
get方法使用第二個參數就表示進行關聯預載入查詢。
#### 關聯更新
一對一的關聯更新如下:
~~~
public function update($id)
{
$user = UserModel::get($id);
$user->name = 'framework';
if ($user->save()) {
// 更新關聯數據
$user->profile->email = 'liu21st@gmail.com';
$user->profile->save();
return '用戶[ ' . $user->name . ' ]更新成功';
} else {
return $user->getError();
}
}
~~~
#### 關聯刪除
關聯刪除代碼如下:
~~~
public function delete($id)
{
$user = UserModel::get($id);
if ($user->delete()) {
// 刪除關聯數據
$user->profile->delete();
return '用戶[ ' . $user->name . ' ]刪除成功';
} else {
return $user->getError();
}
}
~~~