1. 程式人生 > >關聯模型 (1對1)

關聯模型 (1對1)

gpo 才會 默認 別名 reat join ech sts mod

關聯模型 (1對1)

ThinkPHP5.0 的關聯采用了對象化的操作模式,你無需繼承不同的模型類
只是把關聯定義成一個方法,並且直接通過當前模型對象的屬性名獲取定義的關聯數據。

關聯定義:一個user有一份profile

DROP TABLE IF EXISTS `think_user`;
CREATE TABLE IF NOT EXISTS `think_user` (
`id` int(6) UNSIGNED NOT NULL AUTO_INCREMENT,
`nickname` varchar(25) NOT NULL,
`name` varchar(25) NOT NULL,
`password` varchar(50) NOT NULL,
`create_time` int(11) UNSIGNED NOT NULL,
`update_time` int(11) UNSIGNED NOT NULL,
`status` tinyint(1) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `think_profile`;
CREATE TABLE IF NOT EXISTS `think_profile` (
`id` int(6) UNSIGNED NOT NULL AUTO_INCREMENT,
`truename` varchar(25) NOT NULL,
`birthday` int(11) NOT NULL,
`address` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`user_id` int(6) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

hasOne (一個用戶有一份檔案)

步驟一、定義用戶模型,並在用戶模型中定義關聯方法profile()

<?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方法()

hasOne方法有5個參數,依次分別是:
hasOne(‘關聯模型名‘,‘關聯外鍵‘,‘主鍵‘,‘別名定義‘,‘join類型‘)

  1. 關聯那個模型
  2. 關聯表中的哪個字段是本模型的主鍵(也就是關聯本模型的鍵是那個)
  3. 本模型的主鍵是那個
  4. 數據別名定義使用數組
  5. 默認是inner

註意點:

  • 通常關聯模型和當前模型都是相同的命名空間,如果關聯模型在不同的命名空間,需要指定完整的類名,例如:

    // 關聯admin模塊下面的模型對象
    return $this->hasOne(‘\app\admin\Profile‘);
  • 在關聯查詢的時候,默認使用當前模型的名稱(小寫)作為數據表別名,可以指定查詢使用的數據表別名,例如:

    // 用戶HAS ONE檔案關聯
    return $this->hasOne(‘Profile‘,‘user_id‘,‘id‘,[‘user‘=>‘member‘,‘profile‘=>‘info‘]);
  • 要進行模型的關聯操作,我們必須同時定義好關聯模型

步驟二、定義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類型‘)

1. 關聯新增


<?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 = ‘[email protected]‘;
        $user->profile()->save($profile);
        return ‘用戶新增成功‘;
        } else {
        return $user->getError();
        }
    }
}
  1. $profile = new Profile;
  2. $user->profile()->save($profile);

關聯模型的寫入調用了關聯方法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 extends Controller
{
// 關聯新增數據
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‘] = ‘[email protected]‘;
        $user->profile()->save($profile);
        return ‘用戶[ ‘ . $user->name . ‘ ]新增成功‘;
        } else {
        return $user->getError();
        }
}
}

*$user->profile()->save($profile);

2.關聯查詢

一對一的關聯查詢很簡單,直接把關聯對象當成屬性來用即可,例如:

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方法使用第二個參數就表示進行關聯預載入查詢。

  • $user = UserModel::get($id,‘profile‘);

    3.關聯更新

    一對一的關聯更新如下:

    public function update($id)
    {
    $user = UserModel::get($id);
    $user->name = ‘framework‘;
    if ($user->save()) {
    // 更新關聯數據
    $user->profile->email = ‘[email protected]‘;
    $user->profile->save();
    return ‘用戶[ ‘ . $user->name . ‘ ]更新成功‘;
    } else {
    return $user->getError();
    }
    }

4. 關聯刪除

關聯刪除代碼如下:

public function delete($id)
{
    $user = UserModel::get($id);
    if ($user->delete()) {
    // 刪除關聯數據
    $user->profile->delete();
    return ‘用戶[ ‘ . $user->name . ‘ ]刪除成功‘;
    } else {
    return $user->getError();
    }
}

關聯模型 (1對1)