免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
YII Framework學(xué)習(xí)教程

     YII中的DAO(數(shù)據(jù)庫訪問對象)是建立在PHP的PDO之上的,所以你開發(fā)的應(yīng)用可以很容易的在不同的數(shù)據(jù)庫系統(tǒng)平臺之間進(jìn)行切換,而只需要修改少量代碼。YII采用ORM(Object-Relational Mapping)的設(shè)計(jì)模式進(jìn)行數(shù)據(jù)庫編程,簡化了一些繁瑣的的數(shù)據(jù)庫操作。

       在YII中的DAO的相關(guān)類主要存放在/yii_dev/yii/framework/db和/yii_dev/yii/framework/web,通常名稱帶有DB或者Data。

       在YII中操作數(shù)據(jù)庫我們主要是使用CActiveRecord,它繼承CModel。用CActiveRecord可以完成對數(shù)據(jù)CURD操作的大部分任務(wù)。  但是對于有復(fù)雜邏輯的數(shù)據(jù)庫查詢操作,用CActiveRecord就力不從心了,后續(xù)將會講解YII如何處理復(fù)雜的數(shù)據(jù)庫查詢操作。

       在ORM中通常用Object(對象)來表示一個(gè)Relation(關(guān)系),可以理解為一個(gè)類對應(yīng)一個(gè)數(shù)據(jù)表或者視圖。類的屬性可以認(rèn)為是和數(shù)據(jù)表的列一一對應(yīng)的,類中的方法是用于對數(shù)據(jù)庫操作的方法例如CURD。

      這里講一下CActiveRecord如何使用。

      一般如果是基本的操作我們可以用yiic自動(dòng)生產(chǎn)curd系列的操作。這里在不多說明。主要說明如果手寫代碼,我們的程序要遵循的基本規(guī)則。

      1.設(shè)計(jì)表

        開始之前我們先來定義我們要操作的表。這里使用mysql,數(shù)據(jù)庫是testdrive,使用的表結(jié)構(gòu)如下:

       

  1. CREATE TABLE `tbl_user` (  
  2.     `id` INT(11) NOT NULL AUTO_INCREMENT,  
  3.     `username` VARCHAR(128) NOT NULL,  
  4.     `password` VARCHAR(128) NOT NULL,  
  5.     `email` VARCHAR(128) NULL DEFAULT NULL,  
  6.     PRIMARY KEY (`id`)  
  7. )  
  8. COLLATE='utf8_general_ci'  
  9. ENGINE=MyISAM  

       2.配置數(shù)據(jù)庫鏈接

              在/testwebap/protected/config/main.php配置文件

  1. 'db'=>array(  
  2.     'connectionString' => 'mysql:host=localhost;dbname=testdrive',  
  3.     'emulatePrepare' => true,  
  4.     'username' => 'root',  
  5.     'password' => '',  
  6.     'charset' => 'utf8',  
  7. ),  

       3.定義數(shù)據(jù)庫操作類。

           要繼承CActiveRecord ,其實(shí)經(jīng)過前面章節(jié)的說明,這里的代碼完全可以自動(dòng)生成,這里定義基本的類,做說明。基本代碼如下:

  1. <?php  
  2. class TblUser extends CActiveRecord  
  3. {  
  4.     public static function model($className=__CLASS__)  
  5.     {  
  6.         return parent::model($className);  
  7.     }  
  8.     public function tableName()  
  9.     {  
  10.         return 'tbl_user';  
  11.     }  
  12. }  

      4.使用:實(shí)例化我們的數(shù)據(jù)庫操作類。

       在/yii_dev/testwebap/protected/modules/testmod/controllers/DefaultController.php定義DefaultController。具體結(jié)構(gòu)如下:

  1. <?php  
  2.   
  3. class DefaultController extends Controller  
  4. {  
  5.     public function actionIndex()  
  6.     {   
  7.         $this->render('index');  
  8.     }  
  9. }  

      實(shí)例化我們的數(shù)據(jù)庫操作類,具體代碼如下:

  1. <?php  
  2.   
  3. class DefaultController extends Controller  
  4. {  
  5.     public function actionIndex()  
  6.     {   
  7.         $model=new TblUser;  
  8.         var_dump($model);  
  9.         exit;  
  10.         $this->render('index');  
  11.     }  
  12. }  

運(yùn)行http://www.localyii.com/testwebap/index.php/testmod/default/index

如果不出異常,會打印如下類似的信息,表示你的操作類可以正常使用

  1. object(TblUser)#14 (12) { ["_md":"CActiveRecord":private]=> object(CActiveRecordMetaData)#16 (5) { ["tableSchema"]=> object(CMysqlTableSchema)#20 (9) { ["schemaName"]=> NULL ["name"]=> string(8) "tbl_user" ["rawName"]=> string(10) "`tbl_user`" ["primaryKey"]=> string(2) "id" ["sequenceName"]=> string(0) "" ["foreignKeys"]=> array(0) { } ["columns"]=> array(4) { ["id"]=> object(CMysqlColumnSchema)#21 (14) { ["name"]=> string(2) "id" ["rawName"]=> string(4) "`id`" ["allowNull"]=> bool(false) ["dbType"]=> string(7) "int(11)" ["type"]=> string(7) "integer" ["defaultValue"]=> NULL ["size"]=> int(11) ["precision"]=> int(11) ["scale"]=> NULL ["isPrimaryKey"]=> bool(true) ["isForeignKey"]=> bool(false) ["autoIncrement"]=> bool(true) ["_e":"CComponent":private]=> NULL ["_m":"CComponent":private]=> NULL } ["username"]=> object(CMysqlColumnSchema)#22 (14) { ["name"]=> string(8) "username" ["ra  
     

           5.使用:插入一行數(shù)據(jù)。


  1. <?php  
  2. class DefaultController extends Controller  
  3. {  
  4.     public function actionIndex ()  
  5.     {  
  6.         $model = new TblUser();  
  7.         $model->username = 'admin';  
  8.         $model->password = '123456';  
  9.         $model->email = 'admin@admin.com';  
  10.           
  11.         var_dump($model->save());  
  12.         exit();  
  13.         $this->render('index');  
  14.     }  
  15. }  

http://www.localyii.com/testwebap/index.php/testmod/default/index

如果打印的是bool(true),查看一下數(shù)據(jù)庫可以看到,我們的數(shù)據(jù)已經(jīng)存入到數(shù)據(jù)庫中。

 這里TblUser中雖然沒有明確的指定數(shù)據(jù)表的列的名稱,但是我們還是可以直接使用。這都是yii悄悄為我們做的。這樣的操作豈不是很爽。還有TblUser是繼承的CActiveRecord,也繼承與CModel當(dāng)然也是CComponent,所以他們的方法我們都可以使用。修改,刪除,查找,比較,你想要的函數(shù)應(yīng)有盡有,這里不再詳細(xì)做講解,自己慢慢分析代碼,才能更好的掌握這些方法的使用。

       下的時(shí)間交給官方文檔,看看官方文檔講CActiveRecord的常見方法。

        具體網(wǎng)址是:http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.ar

        //詳細(xì)內(nèi)容如下://///////////////

         

Active Record 

雖然 Yii DAO 可以處理幾乎任何數(shù)據(jù)庫相關(guān)的任務(wù), 但很可能我們會花費(fèi) 90% 的時(shí)間以編寫一些執(zhí)行普通 CRUD(create, read, update 和 delete)操作的 SQL 語句。 而且我們的代碼中混雜了SQL語句時(shí)也會變得難以維護(hù)。要解決這些問題,我們可以使用 Active Record。

Active Record (AR) 是一個(gè)流行的 對象-關(guān)系映射 (ORM) 技術(shù)。 每個(gè) AR 類代表一個(gè)數(shù)據(jù)表(或視圖),數(shù)據(jù)表(或視圖)的列在 AR 類中體現(xiàn)為類的屬性,一個(gè) AR 實(shí)例則表示表中的一行。 常見的 CRUD 操作作為 AR 的方法實(shí)現(xiàn)。因此,我們可以以一種更加面向?qū)ο蟮姆绞皆L問數(shù)據(jù)。 例如,我們可以使用以下代碼向 tbl_post 表中插入一個(gè)新行。

$post=new Post;$post->title='sample post';$post->content='post body content';$post->save();

下面我們講解怎樣設(shè)置 AR 并通過它執(zhí)行 CRUD 操作。我們將在下一節(jié)中展示怎樣使用 AR 處理數(shù)據(jù)庫關(guān)系。 為簡單起見,我們使用下面的數(shù)據(jù)表作為此節(jié)中的例子。注意,如果你使用 MySQL 數(shù)據(jù)庫,你應(yīng)該將下面的 SQL 中的 AUTOINCREMENT 替換為 AUTO_INCREMENT。

CREATE TABLE tbl_post (    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,    title VARCHAR(128) NOT NULL,    content TEXT NOT NULL,    create_time INTEGER NOT NULL);

注意: AR 并非要解決所有數(shù)據(jù)庫相關(guān)的任務(wù)。它的最佳應(yīng)用是模型化數(shù)據(jù)表為 PHP 結(jié)構(gòu)和執(zhí)行不包含復(fù)雜 SQL 語句的查詢。 對于復(fù)雜查詢的場景,應(yīng)使用 Yii DAO。

1. 建立數(shù)據(jù)庫連接 

AR 依靠一個(gè)數(shù)據(jù)庫連接以執(zhí)行數(shù)據(jù)庫相關(guān)的操作。默認(rèn)情況下, 它假定 db 應(yīng)用組件提供了所需的CDbConnection 數(shù)據(jù)庫連接實(shí)例。如下應(yīng)用配置提供了一個(gè)例子:

return array(    'components'=>array(        'db'=>array(            'class'=>'system.db.CDbConnection',            'connectionString'=>'sqlite:path/to/dbfile',            // 開啟表結(jié)構(gòu)緩存(schema caching)提高性能            // 'schemaCachingDuration'=>3600,        ),    ),);

提示: 由于 Active Record 依靠表的元數(shù)據(jù)(metadata)測定列的信息,讀取元數(shù)據(jù)并解析需要時(shí)間。 如果你數(shù)據(jù)庫的表結(jié)構(gòu)很少改動(dòng),你應(yīng)該通過配置 CDbConnection::schemaCachingDuration 屬性的值為一個(gè)大于零的值開啟表結(jié)構(gòu)緩存。

對 AR 的支持受 DBMS 的限制,當(dāng)前只支持下列幾種 DBMS:

注意: 1.0.4 版開始支持 Microsoft SQL Server;1.0.5 版開始支持 Oracle。

如果你想使用一個(gè)不是 db 的應(yīng)用組件,或者如果你想使用 AR 處理多個(gè)數(shù)據(jù)庫,你應(yīng)該覆蓋CActiveRecord::getDbConnection()。 CActiveRecord 類是所有 AR 類的基類。

提示: 通過 AR 使用多個(gè)數(shù)據(jù)庫有兩種方式。如果數(shù)據(jù)庫的結(jié)構(gòu)不同,你可以創(chuàng)建不同的 AR 基類實(shí)現(xiàn)不同的 getDbConnection()。否則,動(dòng)態(tài)改變靜態(tài)變量 CActiveRecord::db 是一個(gè)好主意。

2. 定義 AR 類 

要訪問一個(gè)數(shù)據(jù)表,我們首先需要通過集成 CActiveRecord 定義一個(gè) AR 類。 每個(gè) AR 類代表一個(gè)單獨(dú)的數(shù)據(jù)表,一個(gè) AR 實(shí)例則代表那個(gè)表中的一行。 如下例子演示了代表 tbl_post 表的 AR 類的最簡代碼:

class Post extends CActiveRecord{    public static function model($className=__CLASS__)    {        return parent::model($className);    }     public function tableName()    {        return 'tbl_post';    }}

提示: 由于 AR 類經(jīng)常在多處被引用,我們可以導(dǎo)入包含 AR 類的整個(gè)目錄,而不是一個(gè)個(gè)導(dǎo)入。 例如,如果我們所有的 AR 類文件都在 protected/models 目錄中,我們可以配置應(yīng)用如下:

return array(  'import'=>array(      'application.models.*',  ),);

默認(rèn)情況下,AR 類的名字和數(shù)據(jù)表的名字相同。如果不同,請覆蓋 tableName() 方法。 model() 方法為每個(gè) AR 類聲明為如此(稍后解釋)。

信息: 要使用 1.1.0 版本中引入的 表前綴功能 AR 類的 tableName() 方法可以通過如下方式覆蓋

public function tableName(){    return '{{post}}';}

這就是說,我們將返回通過雙大括號括起來的沒有前綴的表名,而不是完整的表的名字。

數(shù)據(jù)表行中列的值可以作為相應(yīng) AR 實(shí)例的屬性訪問。例如,如下代碼設(shè)置了 title 列 (屬性):

$post=new Post;$post->title='a sample post';

雖然我們從未在 Post 類中顯式定義屬性 title,我們還是可以通過上述代碼訪問。 這是因?yàn)?nbsp;title 是tbl_post 表中的一個(gè)列,CActiveRecord 通過PHP的 __get() 魔術(shù)方法使其成為一個(gè)可訪問的屬性。 如果我們嘗試以同樣的方式訪問一個(gè)不存在的列,將會拋出一個(gè)異常。

信息: 此指南中,我們在表名和列名中均使用了小寫字母。 這是因?yàn)椴煌?DBMS 處理大小寫的方式不同。 例如,PostgreSQL 默認(rèn)情況下對列的名字大小寫不敏感,而且我們必須在一個(gè)查詢條件中用引號將大小寫混合的列名引起來。 使用小寫字母可以幫助我們避免此問題。

AR 依靠表中良好定義的主鍵。如果一個(gè)表沒有主鍵,則必須在相應(yīng)的 AR 類中通過如下方式覆蓋 primaryKey()方法指定哪一列或哪幾列作為主鍵。

public function primaryKey(){    return 'id';    // 對于復(fù)合主鍵,要返回一個(gè)類似如下的數(shù)組    // return array('pk1', 'pk2');}

3. 創(chuàng)建記錄 

要向數(shù)據(jù)表中插入新行,我們要?jiǎng)?chuàng)建一個(gè)相應(yīng) AR 類的實(shí)例,設(shè)置其與表的列相關(guān)的屬性,然后調(diào)用 save() 方法完成插入:

$post=new Post;$post->title='sample post';$post->content='content for the sample post';$post->create_time=time();$post->save();

如果表的主鍵是自增的,在插入完成后,AR 實(shí)例將包含一個(gè)更新的主鍵。在上面的例子中, id 屬性將反映出新插入帖子的主鍵值,即使我們從未顯式地改變它。

如果一個(gè)列在表結(jié)構(gòu)中使用了靜態(tài)默認(rèn)值(例如一個(gè)字符串,一個(gè)數(shù)字)定義。則 AR 實(shí)例中相應(yīng)的屬性將在此實(shí)例創(chuàng)建時(shí)自動(dòng)含有此默認(rèn)值。改變此默認(rèn)值的一個(gè)方式就是在 AR 類中顯示定義此屬性:

class Post extends CActiveRecord{    public $title='please enter a title';    ......} $post=new Post;echo $post->title;  // 這兒將顯示: please enter a title

從版本 1.0.2 起,記錄在保存(插入或更新)到數(shù)據(jù)庫之前,其屬性可以賦值為 CDbExpression 類型。 例如,為保存一個(gè)由 MySQL 的 NOW() 函數(shù)返回的時(shí)間戳,我們可以使用如下代碼:

$post=new Post;$post->create_time=new CDbExpression('NOW()');// $post->create_time='NOW()'; 不會起作用,因?yàn)?/span>// 'NOW()' 將會被作為一個(gè)字符串處理。$post->save();

提示: 由于 AR 允許我們無需寫一大堆 SQL 語句就能執(zhí)行數(shù)據(jù)庫操作, 我們經(jīng)常會想知道 AR 在背后到底執(zhí)行了什么 SQL 語句。這可以通過開啟 Yii 的 日志功能 實(shí)現(xiàn)。例如,我們在應(yīng)用配置中開啟了CWebLogRoute ,我們將會在每個(gè)網(wǎng)頁的最后看到執(zhí)行過的 SQL 語句。 從 1.0.5 版本起,我們可以在應(yīng)用配置中設(shè)置 CDbConnection::enableParamLogging 為 true ,這樣綁定在 SQL 語句中的參數(shù)值也會被記錄。

4. 讀取記錄 

要讀取數(shù)據(jù)表中的數(shù)據(jù),我們可以通過如下方式調(diào)用 find 系列方法中的一種:

// 查找滿足指定條件的結(jié)果中的第一行$post=Post::model()->find($condition,$params);// 查找具有指定主鍵值的那一行$post=Post::model()->findByPk($postID,$condition,$params);// 查找具有指定屬性值的行$post=Post::model()->findByAttributes($attributes,$condition,$params);// 通過指定的 SQL 語句查找結(jié)果中的第一行$post=Post::model()->findBySql($sql,$params);

如上所示,我們通過 Post::model() 調(diào)用 find 方法。 請記住,靜態(tài)方法 model() 是每個(gè) AR 類所必須的。 此方法返回在對象上下文中的一個(gè)用于訪問類級別方法(類似于靜態(tài)類方法的東西)的 AR 實(shí)例。

如果 find 方法找到了一個(gè)滿足查詢條件的行,它將返回一個(gè) Post 實(shí)例,實(shí)例的屬性含有數(shù)據(jù)表行中相應(yīng)列的值。 然后我們就可以像讀取普通對象的屬性那樣讀取載入的值,例如 echo $post->title;。

如果使用給定的查詢條件在數(shù)據(jù)庫中沒有找到任何東西, find 方法將返回 null 。

調(diào)用 find 時(shí),我們使用 $condition 和 $params 指定查詢條件。此處 $condition 可以是 SQL 語句中的WHERE 字符串,$params 則是一個(gè)參數(shù)數(shù)組,其中的值應(yīng)綁定到 $condation 中的占位符。例如:

// 查找 postID=10 的那一行$post=Post::model()->find('postID=:postID', array(':postID'=>10));

注意: 在上面的例子中,我們可能需要在特定的 DBMS 中將 postID 列的引用進(jìn)行轉(zhuǎn)義。 例如,如果我們使用 PostgreSQL,我們必須將此表達(dá)式寫為 "postID"=:postID,因?yàn)?PostgreSQL 在默認(rèn)情況下對列名大小寫不敏感。

我們也可以使用 $condition 指定更復(fù)雜的查詢條件。 不使用字符串,我們可以讓 $condition 成為一個(gè)CDbCriteria 的實(shí)例,它允許我們指定不限于 WHERE 的條件。 例如:

$criteria=new CDbCriteria;$criteria->select='title';  // 只選擇 'title' 列$criteria->condition='postID=:postID';$criteria->params=array(':postID'=>10);$post=Post::model()->find($criteria); // $params 不需要了

注意,當(dāng)使用 CDbCriteria 作為查詢條件時(shí),$params 參數(shù)不再需要了,因?yàn)樗梢栽?nbsp;CDbCriteria 中指定,就像上面那樣。

一種替代 CDbCriteria 的方法是給 find 方法傳遞一個(gè)數(shù)組。 數(shù)組的鍵和值各自對應(yīng)標(biāo)準(zhǔn)(criterion)的屬性名和值,上面的例子可以重寫為如下:

$post=Post::model()->find(array(    'select'=>'title',    'condition'=>'postID=:postID',    'params'=>array(':postID'=>10),));

信息: 當(dāng)一個(gè)查詢條件是關(guān)于按指定的值匹配幾個(gè)列時(shí),我們可以使用 findByAttributes()。我們使$attributes 參數(shù)是一個(gè)以列名做索引的值的數(shù)組。在一些框架中,此任務(wù)可以通過調(diào)用類似findByNameAndTitle 的方法實(shí)現(xiàn)。雖然此方法看起來很誘人, 但它常常引起混淆,沖突和比如列名大小寫敏感的問題。

當(dāng)有多行數(shù)據(jù)匹配指定的查詢條件時(shí),我們可以通過下面的 findAll 方法將他們?nèi)繋Щ亍?每個(gè)都有其各自的find 方法,就像我們已經(jīng)講過的那樣。

// 查找滿足指定條件的所有行$posts=Post::model()->findAll($condition,$params);// 查找?guī)в兄付ㄖ麈I的所有行$posts=Post::model()->findAllByPk($postIDs,$condition,$params);// 查找?guī)в兄付▽傩灾档乃行?/span>$posts=Post::model()->findAllByAttributes($attributes,$condition,$params);// 通過指定的SQL語句查找所有行$posts=Post::model()->findAllBySql($sql,$params);

如果沒有任何東西符合查詢條件,findAll 將返回一個(gè)空數(shù)組。這跟 find 不同,find 會在沒有找到什么東西時(shí)返回 null。

除了上面講述的 find 和 findAll 方法,為了方便,(Yii)還提供了如下方法:

// 獲取滿足指定條件的行數(shù)$n=Post::model()->count($condition,$params);// 通過指定的 SQL 獲取結(jié)果行數(shù)$n=Post::model()->countBySql($sql,$params);// 檢查是否至少有一行復(fù)合指定的條件$exists=Post::model()->exists($condition,$params);

5. 更新記錄 

在 AR 實(shí)例填充了列的值之后,我們可以改變它們并把它們存回?cái)?shù)據(jù)表。

$post=Post::model()->findByPk(10);$post->title='new post title';$post->save(); // 將更改保存到數(shù)據(jù)庫

正如我們可以看到的,我們使用同樣的 save() 方法執(zhí)行插入和更新操作。 如果一個(gè) AR 實(shí)例是使用 new 操作符創(chuàng)建的,調(diào)用 save() 將會向數(shù)據(jù)表中插入一行新數(shù)據(jù); 如果 AR 實(shí)例是某個(gè) find 或 findAll 方法的結(jié)果,調(diào)用save() 將更新表中現(xiàn)有的行。 實(shí)際上,我們是使用 CActiveRecord::isNewRecord 說明一個(gè) AR 實(shí)例是不是新的。

直接更新數(shù)據(jù)表中的一行或多行而不首先載入也是可行的。 AR 提供了如下方便的類級別方法實(shí)現(xiàn)此目的:

// 更新符合指定條件的行Post::model()->updateAll($attributes,$condition,$params);// 更新符合指定條件和主鍵的行Post::model()->updateByPk($pk,$attributes,$condition,$params);// 更新滿足指定條件的行的計(jì)數(shù)列Post::model()->updateCounters($counters,$condition,$params);

在上面的代碼中, $attributes 是一個(gè)含有以 列名作索引的列值的數(shù)組; $counters 是一個(gè)由列名索引的可增加的值的數(shù)組;$condition 和 $params 在前面的段落中已有描述。

6. 刪除記錄 

如果一個(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)沒了。

使用下面的類級別代碼,可以無需首先加載行就可以刪除它。

// 刪除符合指定條件的行Post::model()->deleteAll($condition,$params);// 刪除符合指定條件和主鍵的行Post::model()->deleteByPk($pk,$condition,$params);

7. 數(shù)據(jù)驗(yàn)證 

當(dāng)插入或更新一行時(shí),我們常常需要檢查列的值是否符合相應(yīng)的規(guī)則。 如果列的值是由最終用戶提供的,這一點(diǎn)就更加重要??傮w來說,我們永遠(yuǎn)不能相信任何來自客戶端的數(shù)據(jù)。

當(dāng)調(diào)用 save() 時(shí), AR 會自動(dòng)執(zhí)行數(shù)據(jù)驗(yàn)證。 驗(yàn)證是基于在 AR 類的 rules() 方法中指定的規(guī)則進(jìn)行的。 關(guān)于驗(yàn)證規(guī)則的更多詳情,請參考 聲明驗(yàn)證規(guī)則 一節(jié)。 下面是保存記錄時(shí)所需的典型的工作流。

if($post->save()){    // 數(shù)據(jù)有效且成功插入/更新}else{    // 數(shù)據(jù)無效,調(diào)用  getErrors() 提取錯(cuò)誤信息}

當(dāng)要插入或更新的數(shù)據(jù)由最終用戶在一個(gè) HTML 表單中提交時(shí),我們需要將其賦給相應(yīng)的 AR 屬性。 我們可以通過類似如下的方式實(shí)現(xiàn):

$post->title=$_POST['title'];$post->content=$_POST['content'];$post->save();

如果有很多列,我們可以看到一個(gè)用于這種復(fù)制的很長的列表。 這可以通過使用如下所示的 attributes 屬性簡化操作。 更多信息可以在 安全的特性賦值 一節(jié)和 創(chuàng)建動(dòng)作 一節(jié)找到。

// 假設(shè) $_POST['Post'] 是一個(gè)以列名索引列值為值的數(shù)組$post->attributes=$_POST['Post'];$post->save();

8. 對比記錄 

類似于表記錄,AR 實(shí)例由其主鍵值來識別。 因此,要對比兩個(gè) AR 實(shí)例,假設(shè)它們屬于相同的 AR 類, 我們只需要對比它們的主鍵值。 然而,一個(gè)更簡單的方式是調(diào)用 CActiveRecord::equals()。

信息: 不同于 AR 在其他框架的執(zhí)行, Yii 在其 AR 中支持多個(gè)主鍵. 一個(gè)復(fù)合主鍵由兩個(gè)或更多字段構(gòu)成。相應(yīng)地, 主鍵值在 Yii 中表現(xiàn)為一個(gè)數(shù)組. primaryKey 屬性給出了一個(gè) AR 實(shí)例的主鍵值。

9. 自定義 

CActiveRecord 提供了幾個(gè)占位符方法,它們可以在子類中被覆蓋以自定義其工作流。

  • beforeValidate 和
  • beforeSave 和 afterSave: 這兩個(gè)將在保存 AR 實(shí)例之前和之后被調(diào)用。

  • beforeDelete 和 afterDelete: 這兩個(gè)將在一個(gè) AR 實(shí)例被刪除之前和之后被調(diào)用。

  • afterConstruct: 這個(gè)將在每個(gè)使用 new 操作符創(chuàng)建 AR 實(shí)例后被調(diào)用。

  • beforeFind: 這個(gè)將在一個(gè) AR 查找器被用于執(zhí)行查詢(例如 find()findAll())之前被調(diào)用。 1.0.9 版本開始可用。

  • afterFind: 這個(gè)將在每個(gè) AR 實(shí)例作為一個(gè)查詢結(jié)果創(chuàng)建時(shí)被調(diào)用。

10. 使用 AR 處理事務(wù) 

每個(gè) AR 實(shí)例都含有一個(gè)屬性名叫 dbConnection ,是一個(gè) CDbConnection 的實(shí)例,這樣我們可以在需要時(shí)配合 AR 使用由 Yii DAO 提供的 事務(wù) 功能:

$model=Post::model();$transaction=$model->dbConnection->beginTransaction();try{    // 查找和保存是可能由另一個(gè)請求干預(yù)的兩個(gè)步驟    // 這樣我們使用一個(gè)事務(wù)以確保其一致性和完整性    $post=$model->findByPk(10);    $post->title='new post title';    $post->save();    $transaction->commit();}catch(Exception $e){    $transaction->rollBack();}

11. 命名范圍 

Note: 對命名范圍的支持從版本 1.0.5 開始。 命名范圍的最初想法來源于 Ruby on Rails.

命名范圍(named scope) 表示一個(gè) 命名的(named) 查詢規(guī)則,它可以和其他命名范圍聯(lián)合使用并應(yīng)用于 Active Record 查詢。

命名范圍主要是在 CActiveRecord::scopes() 方法中以名字-規(guī)則對的方式聲明。 如下代碼在 Post 模型類中聲明了兩個(gè)命名范圍, published 和 recently。

class Post extends CActiveRecord{    ......    public function scopes()    {        return array(            'published'=>array(                'condition'=>'status=1',            ),            'recently'=>array(                'order'=>'create_time DESC',                'limit'=>5,            ),        );    }}

每個(gè)命名范圍聲明為一個(gè)可用于初始化 CDbCriteria 實(shí)例的數(shù)組。 例如,recently 命名范圍指定 order 屬性為create_time DESC , limit 屬性為 5。他們翻譯為查詢規(guī)則后就會返回最近的5篇帖子。

命名范圍多用作 find 方法調(diào)用的修改器。 幾個(gè)命名范圍可以鏈到一起形成一個(gè)更有約束性的查詢結(jié)果集。例如, 要找到最近發(fā)布的帖子, 我們可以使用如下代碼:

$posts=Post::model()->published()->recently()->findAll();

總體來說,命名范圍必須出現(xiàn)在一個(gè) find 方法調(diào)用的左邊。 它們中的每一個(gè)都提供一個(gè)查詢規(guī)則,并聯(lián)合到其他規(guī)則, 包括傳遞給 find 方法調(diào)用的那一個(gè)。 最終結(jié)果就像給一個(gè)查詢添加了一系列過濾器。

從版本 1.0.6 開始,命名范圍也可用于 update 和 delete 方法。 例如,如下代碼將刪除所有最近發(fā)布的帖子:

Post::model()->published()->recently()->delete();

注意: 命名范圍只能用于類級別方法。也就是說,此方法必須使用 ClassName::model() 調(diào)用。

參數(shù)化的命名范圍

命名范圍可以參數(shù)化。例如, 我們想自定義 recently 命名范圍中指定的帖子數(shù)量,要實(shí)現(xiàn)此目的,不是在CActiveRecord::scopes 方法中聲明命名范圍, 而是需要定義一個(gè)名字和此命名范圍的名字相同的方法:

public function recently($limit=5){    $this->getDbCriteria()->mergeWith(array(        'order'=>'create_time DESC',        'limit'=>$limit,    ));    return $this;}

然后,我們就可以使用如下語句獲取3條最近發(fā)布的帖子。

$posts=Post::model()->published()->recently(3)->findAll();

上面的代碼中,如果我們沒有提供參數(shù) 3,我們將默認(rèn)獲取 5 條最近發(fā)布的帖子。

默認(rèn)的命名范圍

模型類可以有一個(gè)默認(rèn)命名范圍,它將應(yīng)用于所有 (包括相關(guān)的那些) 關(guān)于此模型的查詢。例如,一個(gè)支持多種語言的網(wǎng)站可能只想顯示當(dāng)前用戶所指定的語言的內(nèi)容。 因?yàn)榭赡軙泻芏嚓P(guān)于此網(wǎng)站內(nèi)容的查詢, 我們可以定義一個(gè)默認(rèn)的命名范圍以解決此問題。 為實(shí)現(xiàn)此目的,我們覆蓋 CActiveRecord::defaultScope 方法如下:

class Content extends CActiveRecord{    public function defaultScope()    {        return array(            'condition'=>"language='".Yii::app()->language."'",        );    }}

現(xiàn)在,如果下面的方法被調(diào)用,將會自動(dòng)使用上面定義的查詢規(guī)則:

$contents=Content::model()->findAll();

注意,默認(rèn)的命名范圍只會應(yīng)用于 SELECT 查詢。INSERTUPDATE 和 DELETE 查詢將被忽略。



 

       

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
YII AR
yii中數(shù)據(jù)模型的使用
Yii2 advanced版API接口開發(fā) 基于RESTful架構(gòu)的 配置、實(shí)現(xiàn)、測試
MVC
創(chuàng)建模型
優(yōu)化wordpress數(shù)據(jù)庫之wp
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服