首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

ThinkPHP 關聯模型操作完整指南:定義、查詢、寫入、更新與刪除

     編輯:PHP 綜合知識

ThinkPHP 的關聯模型(RelationModel)提供了優雅的方式處理資料表間的關聯關係,支援四種核心關聯類型:HAS_ONE、BELONGS_TO、HAS_MANY、MANY_TO_MANY。本文系統整理關聯定義語法、常用屬性參數,並示範關聯查詢、寫入、更新、刪除的完整操作流程。

關聯類型總覽

關聯類型關係描述典型場景
HAS_ONE一對一(擁有)User → Profile
BELONGS_TO一對一(屬於)User → Dept(用戶屬於部門)
HAS_MANY一對多User → Articles(用戶擁有多篇文章)
MANY_TO_MANY多對多User ↔ Group(透過中間表 think_group_user)

關聯定義統一格式

所有關聯定義集中在模型類的 $_link 成員變數中,模型需繼承 RelationModel:

class UserModel extends RelationModel {
    protected $_link = array(
        '關聯名稱' => array(
            'mapping_type'  => HAS_ONE,      // 關聯類型(必填)
            'class_name'    => 'Profile',    // 關聯模型類名
            'mapping_name'  => 'profile',    // 映射名稱(查詢結果鍵名)
            'foreign_key'   => 'user_id',    // 外鍵名稱
            'condition'     => 'status=1',   // 關聯條件
            'mapping_fields'=> 'id,name',    // 要查詢的字段
            'as_fields'     => 'name:profile_name', // 字段映射到主模型
            // ... 更多屬性見下文
        ),
    );
}

四大關聯類型詳細屬性

HAS_ONE 一對一(擁有)

'Profile' => array(
    'mapping_type'  => HAS_ONE,
    'class_name'    => 'Profile',
    'foreign_key'   => 'user_id',      // Profile 表中的外鍵
    'mapping_name'  => 'profile',
    'mapping_fields'=> 'email,nickname',
    'as_fields'     => 'nickname:profile_nickname',
)

BELONGS_TO 一對一(屬於)

'Dept' => array(
    'mapping_type'   => BELONGS_TO,
    'class_name'     => 'Dept',
    'foreign_key'    => 'dept_id',     // User 表中的外鍵
    'mapping_name'   => 'dept',
    'parent_key'     => 'id',          // 自引用關聯時使用
)

HAS_MANY 一對多

'Article' => array(
    'mapping_type'   => HAS_MANY,
    'class_name'     => 'Article',
    'foreign_key'    => 'user_id',
    'mapping_name'   => 'articles',
    'mapping_order'  => 'create_time DESC',
    'mapping_limit'  => '10',
    'mapping_fields' => 'id,title,create_time',
)

MANY_TO_MANY 多對多

'Group' => array(
    'mapping_type'      => MANY_TO_MANY,
    'class_name'        => 'Group',
    'mapping_name'      => 'groups',
    'foreign_key'       => 'user_id',          // 中間表中的用戶外鍵
    'relation_foreign_key' => 'group_id',     // 中間表中的群組外鍵
    'relation_table'    => 'think_group_user', // 中間表名
    'mapping_order'     => 'id DESC',
    'mapping_limit'     => '20',
)

關聯查詢:relation() 方法

使用 relation(true) 啟用所有定義的關聯,或傳入陣列指定部分關聯:

$User = D('User');
// 1. 載入所有關聯
$user = $User->relation(true)->find(1);

// 2. 僅載入指定關聯
$user = $User->relation('Profile,Article')->find(1);

// 結果範例
array(
    'id'       => 1,
    'account'  => 'ThinkPHP',
    'password' => '123456',
    'Profile'  => array('email' => 'liu21st@gmail.com', 'nickname' => '流年'),
    'Article'  => array( /* 文章列表 */ ),
)

關聯寫入:自動同步關聯資料

$User = D('User');
$data = array(
    'account'  => 'ThinkPHP',
    'password' => '123456',
    'Profile'  => array(
        'email'    => 'liu21st@gmail.com',
        'nickname' => '流年',
    ),
);
$result = $User->relation(true)->add($data);
// 會自動寫入 user 表與 profile 表,並正確關聯外鍵

關聯更新

$data = array(
    'account'  => 'ThinkPHP',
    'password' => '123456',
    'Profile'  => array(
        'email'    => 'liu21st@gmail.com',
        'nickname' => '流年',
    ),
);
$result = $User->relation(true)->where('id=3')->save($data);

關聯刪除

// 刪除用戶時,根據關聯定義可級聯刪除關聯資料
$result = $User->relation(true)->delete('3');

注意:級聯刪除行為取決於關聯類型與資料庫外鍵約束,建議在關聯定義中明確 condition 或配合資料庫層面的 ON DELETE CASCADE。

最佳實踐建議

  • 命名規範:關聯名稱($_link 鍵名)建議使用駝峰式,與模型類名一致。
  • 按需載入:避免在列表頁面使用 relation(true) 載入所有關聯,造成 N+1 查詢問題;改用 relation('Profile') 指定所需關聯。
  • 字段限制:善用 mapping_fields 只選取必要欄位,減少資料傳輸量。
  • 中間表索引:多對多關聯的中間表務必在兩個外鍵欄位建立聯合索引。

掌握 ThinkPHP 關聯模型,能讓資料庫操作代碼更符合領域模型思維,減少手動 Join 與資料組裝的樣板代碼,提升開發效率與可維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved