首頁  >  文章  >  後端開發  >  PHP開發框架Yii Framework教學(27) 資料庫-關聯Active Record範例

PHP開發框架Yii Framework教學(27) 資料庫-關聯Active Record範例

黄舟
黄舟原創
2017-01-22 09:30:551350瀏覽

我們已經了解如何使用 Active Record (AR) 從單一資料表中取得資料。 在本節中,我們講解如何使用 AR 連接多個相關 資料表並取回關聯(join)後的資料集。

為了使用關係型 AR,我們建議在需要關聯的表中定義主鍵-外鍵約束。這些約 束可以幫助保證相關資料的一致性和完整性。

本例透過修改Yii Framework 開發教學(25) 資料庫-Query Builder範例來 介紹多個有關聯的表格如何使用Active Record。

在我們使用 AR 執行關聯查詢之前,我們需要讓 AR 知道一個 AR 類別是怎麼 樣關聯到另一個的。

兩個 AR 類別之間的關係直接透過 AR 類別所代表的資料表之間的關係相關聯。 從資料庫的角度來說, 表A 和B 之間有三種關係:一對多(one-to-many,例如tbl_user 和tbl_post),一對一( one-to-one 例如tbl_user 和tbl_profile)和多對多(many-to-many 例如tbl_category 和tbl_post)。 在AR 中,有四種關係:

BELONGS_TO( 屬於): 如果表A 和B 之間的關係是一對多,則表B 屬於表A (例如Post 屬於User);

HAS_MANY(有多個): 如果表A 和B 之間的關係是一對多,則A 有多個B (例如User 有多個Post);

HAS_ONE(有一個): 這是HAS_MANY 的一個特例,A 最多有一個B (例如User 最多有一個Profile);

MANY_MANY: 這個對應於資料庫中的多對多關係。 由於多數 DBMS 不直接支援 多對多 關係,因此需要有一個關聯表將 多對多 關係分割為 一對多 關係。 在我們的範例資料結構中, tbl_post_category 就是用於此目的的。在 AR 術語中,我們可以解釋 MANY_MANY 為 BELONGS_TO 和 HAS_MANY 的組合。 例如 ,Post 屬於多個(belongs to many) Category ,Category 有多個(has many) Post.

AR 中定義關係需要覆蓋 CActiveRecord 中的 relations() 方法。此方法傳回一個關係配置陣列。每個數組元素透過如下格式表示單一的關係。

在Query Builder中我們使用了下面SQL查詢語句

SELECT c.FirstName, c.LastName , c.Address,c.Email
FROM customer c
INNER JOIN
employee e
ON c.SupportRepId=e.EmployeeId


WHERE e.EmployeeId=4涉及兩個表格Employee 和Customer,Employee和Customer之間是一對多的關係,也就是說一個員工可以負責多個客戶。 Employee到Customer的關係式為HAS_MANY, Customer到Employee的關係式為HAS_ONE。因此可以定義 Employee和Customer如下:

//Customer.phpclass Customer extends CActiveRecord{
public static function model($className=__CLASS__){return parent::model($className);}
public function tableName(){return 'Customer';}
}
//Employee.phpclass Employee extends CActiveRecord{
public static function model($className=__CLASS__){return parent::model($className);}
public function tableName(){return 'Employee';}
public function relations(){return array('customers'=>array(self::HAS_MANY, 'Customer', 'SupportRepId'),
);}}

因為本例只使用到由Employee查詢對應的Customer,因此只為類別定義了relations方法。對應的表和外鍵為Customer 和SupportRepId。
接著修改SiteController的indexAction方法:

public function actionIndex(){
$employee=Employee::model()->findByPk(4);
$this->render('index', array('model' => $employee->customers,
));}

AR 類別中的關係定義為每個關係式為類別中隱式新增了一個屬性。在一個關聯查詢執行後,對應的屬性將會被以關聯的 AR 實例填入。因此由$employee->customers可以查詢到Employee對應的Customers記錄。
執行關聯查詢最簡單的方法是讀取 取一個 AR 實例中的關聯屬性。如果此屬性以前沒有被訪問過,則一個關聯查詢將被初始化,它將兩個表關聯並使用當前 AR 實 例的主鍵過濾。 查詢結果將以所關聯 AR 類別的實例的方式儲存到屬性中。這就是傳說中的 懶惰式加載(lazy loading,也可譯 為延遲加載) 方式,例如,關聯查詢只在關聯的對象首次被訪問時執行。
本例使用的為延遲加載,延遲加載在某些情況 下並不高效。如果我們想要取得 N 個貼文的作者,使用這種延遲載入將會導致執行 N 個關聯查詢。 在這種情況下,我們應該改為 使用 渴求式加載(eager loading)方式。
渴求式載入方式會在取得主 AR 實例的同時取得關聯的 AR 實例。 這是透過 在使用 AR 中的 find 或 findAll 方法時配合使用 with 方法完成的。例如:

$employee=Post::model()->with ('customers')->findAll();

最後修改一下顯示結果的View的程式碼:

$customer){
echo 'First Name:' . $customer->FirstName . '';
echo 'Last Name:' . $customer->LastName . '';
echo 'Address:' . $customer->Address . '';
echo 'Email:' . $customer->Email . '';
echo '----------------------';}
?>

不同的資料對列名大小寫處理方式不同,有的資料庫區分大小寫,保險起見,Customer的屬性使用和列定義相同的大小寫。

PHP開發框架Yii Framework教學(27) 資料庫-關聯Active Record範例

本例介紹了關聯Active Record的最基本的用法,其它功能和屬性可以參見Yii中文文檔,此外如果借助類似CodeSmith這樣的工具,如果能夠自動生成數據庫定義的ActiveRecord代碼,就可以大大減輕程式設計師的程式碼手動編寫工作量。

此外,使用Active Record的便利性是以效能為代價的,通常情況下使用Active Record與使用DAO讀寫資料庫效能相比要差一 個層級。下表為一個參考值,找出200個演員和1000部電影。

PHP開發框架Yii Framework教學(27) 資料庫-關聯Active Record範例

以上就是PHP開發框架Yii Framework教程(27) 資料庫-關聯Active Record範例的內容,更多相關內容請關注PHP中文網(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn