Contents
1 創(chuàng)建記錄
2 讀取記錄
3 更新記錄
4 刪除記錄
使用 Java 或是.Net 寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用,很多人都用過(guò) ibernate(或 NHibernate)可以大大簡(jiǎn)化數(shù)據(jù)庫(kù)編程,而以對(duì)象的方式來(lái)讀寫(xiě)數(shù)據(jù)庫(kù)(ORM),Yii 提供的 Active Record (AR) 也是一個(gè)流行的 對(duì)象-關(guān)系映射 (ORM) 技術(shù)。每個(gè) AR 類代表一個(gè)數(shù)據(jù)表(或視圖),數(shù)據(jù)表(或視圖)的列在 AR 類中體現(xiàn)為類的屬性,一個(gè) AR 實(shí)例則表示表中的一行。 常見(jiàn)的 CRUD 操作作為 AR 的方法實(shí)現(xiàn)。因此,我們可以以一種更加面向?qū)ο蟮姆绞皆L問(wèn)數(shù)據(jù)。
這里修改 Yii Framework 開(kāi)發(fā)教程(24) 數(shù)據(jù)庫(kù)-DAO 示例 ,看看使用 Active Record 如何讀取 Employee 表。
要訪問(wèn)一個(gè)數(shù)據(jù)表,我們首先需要通過(guò)集成 CActiveRecord 定義一個(gè) AR 類。 每個(gè) AR 類代表一個(gè)單獨(dú)的數(shù)據(jù)表,一個(gè) AR 實(shí)例則代表那個(gè)表中的一行。
由于 AR 類經(jīng)常在多處被引用,我們可以導(dǎo)入包含 AR 類的整個(gè)目錄,而不是一個(gè)個(gè)導(dǎo)入。 例如,如果我們所有的 AR 類文件都在 protected/models 目錄中,我們可以配置應(yīng)用如下
'import'=>array(
'application.models.*',
),
本例定義 Employee 類如下:
class Employee extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'Employee';
}
}
數(shù)據(jù)表行中列的值可以作為相應(yīng) AR 實(shí)例的屬性訪問(wèn)。比如 $employee->EmployeeId 可以訪問(wèn) Employee 的 EmployeeId 字段。
本例只是讀取 Employee 表,修改 SiteController 的 indexAction 方法:
public function actionIndex()
{
$model = Employee::model()->findAll();
$this->render('index', array(
'model' => $model,
));
}
可以看到只要一行代碼 Employee::model()->findAll()就實(shí)現(xiàn)讀取數(shù)據(jù)庫(kù)表并賦值功能,來(lái)看看對(duì)應(yīng)的顯示記錄的代碼:
<?php foreach($model as $employee)
{
echo 'EmployeeId:' . $employee->EmployeeId . '<br />';
echo 'First Name:' . $employee->FirstName . '<br />';
echo 'Last Name:' . $employee->LastName . '<br />';
echo 'Title:' . $employee->Title . '<br />';
echo 'Address:' . $employee->Address . '<br />';
echo 'Email:' . $employee->Email . '<br />';
echo '---------------------- <br />';
}
?>
可以看到使用 AR 可以通過(guò)數(shù)據(jù)庫(kù)表的字段名(區(qū)分大小寫(xiě))直接訪問(wèn)某個(gè)字段值,而無(wú)需在類 Employee 定義,從而大大簡(jiǎn)化代碼。 在前面介紹 Model 時(shí)說(shuō)過(guò) CModel 有兩個(gè)子類,一個(gè)是 FormModel,另外一個(gè)就是 CActiveRecord,CActiveRecord 定義了數(shù)據(jù)庫(kù)訪問(wèn)的CRUD方法,比如
要向數(shù)據(jù)表中插入新行,我們要?jiǎng)?chuàng)建一個(gè)相應(yīng) AR 類的實(shí)例,設(shè)置其與表的列相關(guān)的屬性,然后調(diào)用 save() 方法完成插入
$employee=new Employee;
$employee->FirstName='James';
$employee->LastName='Shen';
...
$employee->save()
如果表的主鍵是自增的,在插入完成后,AR 實(shí)例將包含一個(gè)更新的主鍵。如果一個(gè)列在表結(jié)構(gòu)中使用了靜態(tài)默認(rèn)值(例如一個(gè)字符串,一個(gè)數(shù)字)定義。
要讀取數(shù)據(jù)表中的數(shù)據(jù),我們可以通過(guò)如下方式調(diào)用 find 系列方法中的一種
// 查找滿足指定條件的結(jié)果中的第一行
$post=Post::model()->find($condition,$params);
// 查找具有指定主鍵值的那一行
$post=Post::model()->findByPk($postID,$condition,$params);
// 查找具有指定屬性值的行
$post=Post::model()->findByAttributes($attributes,$condition,$params);
// 通過(guò)指定的 SQL 語(yǔ)句查找結(jié)果中的第一行
$post=Post::model()->findBySql($sql,$params);
如上所示,我們通過(guò) Post::model() 調(diào)用 find 方法。 請(qǐng)記住,靜態(tài)方法 model() 是每個(gè) AR 類所必須的。 此方法返回在對(duì)象上下文中的一個(gè)用于訪問(wèn)類級(jí)別方法(類似于靜態(tài)類方法的東西)的 AR 實(shí)例。
如果 find 方法找到了一個(gè)滿足查詢條件的行,它將返回一個(gè) Post 實(shí)例,實(shí)例的屬性含有數(shù)據(jù)表行中相應(yīng)列的值。 然后我們就可以像讀取普通對(duì)象的屬性那樣讀取載入的值,例如 echo $post->title;。
如果使用給定的查詢條件在數(shù)據(jù)庫(kù)中沒(méi)有找到任何東西, find 方法將返回 null 。
調(diào)用 find 時(shí),我們使用 $condition 和 $params 指定查詢條件。此處 $condition 可以是 SQL 語(yǔ)句中的 WHERE 字符串,$params 則是一個(gè)參數(shù)數(shù)組,其中的值應(yīng)綁定到 $condation 中的占位符。
在 AR 實(shí)例填充了列的值之后,我們可以改變它們并把它們存回?cái)?shù)據(jù)表。
$post=Post::model()->findByPk(10);
$post->title='new post title';
$post->save(); // 將更改保存到數(shù)據(jù)庫(kù)
如果一個(gè) AR 實(shí)例被一行數(shù)據(jù)填充,我們也可以刪除此行數(shù)據(jù)
$post=Post::model()->findByPk(10); // 假設(shè)有一個(gè)帖子,其 ID 為 10
$post->delete(); // 從數(shù)據(jù)表中刪除此行
注意,刪除之后, AR 實(shí)例仍然不變,但數(shù)據(jù)表中相應(yīng)的行已經(jīng)沒(méi)了
其它可以參見(jiàn) Yii 中文文檔,這里不再詳細(xì)復(fù)述了。
本例顯示結(jié)果:
http://wiki.jikexueyuan.com/project/yii-development-tutorial/images/26.1.jpg" alt="picture26.1" />
本例下載