【Yii】數據庫讀寫方法:AR模型和DAO方法


一、AR模型方法

AR模型是ORM方式的一種,其將SQL查詢進行封裝,使得數據庫讀寫更加方便便捷。其中一個AR類代表數據庫中的一張表。

1.類的定義(Model模型)

定義方式如下:

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

這是一個Model類的最小代碼。

2.新增記錄

 

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

 

3.查詢

查詢語句比較復雜,主要有四種。

 

//  find the first row satisfying the specified condition
$post=Post::model()->find( $condition, $params);
//  find the row with the specified primary key
$post=Post::model()->findByPk( $postID, $condition, $params);
//  find the row with the specified attribute values
$post=Post::model()->findByAttributes( $attributes, $condition, $params);
//  find the first row using the specified SQL statement
$post=Post::model()->findBySql( $sql, $params);

 

其中$condition部分就是SQL語句的WHERE部分,$params就是$condition里面需要的參數。示例:

 

//  find the row with postID=10
$post=Post::model()->find('postID=:postID',  array(':postID'=>10));

 

同時也可以使用CDbCriteria類來配置查詢條件。示例如下:

 

$criteria= new CDbCriteria;
$criteria->select='title';   //  only select the 'title' column
$criteria->condition='postID=:postID';
$criteria->params= array(':postID'=>10);
$post=Post::model()->find( $criteria);  //  $params is not needed

 

此時就無需$params參數了。

上述是查詢單條記錄,如果要查詢多條記錄則使用:

 

//  find all rows satisfying the specified condition
$posts=Post::model()->findAll( $condition, $params);
//  find all rows with the specified primary keys
$posts=Post::model()->findAllByPk( $postIDs, $condition, $params);
//  find all rows with the specified attribute values
$posts=Post::model()->findAllByAttributes( $attributes, $condition, $params);
//  find all rows using the specified SQL statement
$posts=Post::model()->findAllBySql( $sql, $params);

 

4.更新記錄

更新記錄也可以用save()函數。AR模型會智能判定,若對象由new創建則新建記錄,若對象是從數據庫中的查詢結果,則save函數就變成了更新。

然而更新也有特定的函數:

//  update the rows matching the specified condition
Post::model()->updateAll( $attributes, $condition, $params);
//  update the rows matching the specified condition and primary key(s)
Post::model()->updateByPk( $pk, $attributes, $condition, $params);
//  update counter columns in the rows satisfying the specified conditions
Post::model()->updateCounters( $counters, $condition, $params);

 

5.刪除記錄

先查詢后刪除:

 

$post=Post::model()->findByPk(10);  //  assuming there is a post whose ID is 10
$post->delete();  //  delete the row from the database table

 

直接刪除:

//  delete the rows matching the specified condition
Post::model()->deleteAll( $condition, $params);
//  delete the rows matching the specified condition and primary key(s)
Post::model()->deleteByPk( $pk, $condition, $params);

 

6.從表單直接提交到數據庫

如果數據表的項太多,插入新記錄的時候參數列表可能會很長,這時候可以使用attributes屬性來承接由表單POST過來的參數。(未測試)

 

//  assume $_POST['Post'] is an array of column values indexed by column names
$post->attributes= $_POST['Post'];
$post->save();

 

7.函數重載

在執行記錄的時候可以伴隨着函數調用,這些函數主要有:beforeValidate, afterValidate, beforeSave, afterSave, beforeDelete, afterDelete, afterConstruct, beforeFind, afterFind, 函數名可以看出是什么意思了。

8. 使用事務

事務可以將讀寫操作作為一個整體進行,有效防止數據庫讀寫出錯。

 

$model=Post::model();
$transaction= $model->dbConnection->beginTransaction();
try
{
     //  find and save are two steps which may be intervened by another request
    // we therefore use a transaction to ensure consistency and integrity

     $post= $model->findByPk(10);
     $post->title='new post title';
     $post->save();
     $transaction->commit();
}
catch( Exception  $e)
{
     $transaction->rollback();
}

 

二、DAO使用

DAO(數據訪問對象)對訪問存儲在不同數據庫管理系統(DBMS)中的數據提供了一個通用的API。因此,在將底層 DBMS 更換為另一個時,無需修改使用了 DAO 訪問數據的代碼。

上面看到AR的方式很方便和便捷,然而其只能處理簡單數據模型,如果需要讀寫多個數據表或者設計聯合查詢,AR方式往往很有限,這時候就需要使用DAO方式。

1. 建立連接

 

$connection= new CDbConnection( $dsn, $username, $password);
//  建立連接。你可以使用  try...catch 捕獲可能拋出的異常
$connection->active= true;
......
$connection->active= false;   //  關閉連接

 

2.執行SQL語句

 

$connection=Yii::app()->db;    //  假設你已經建立了一個 "db" 連接
// 如果沒有,你可能需要顯式建立一個連接:
// $connection=new CDbConnection($dsn,$username,$password);

$command= $connection->createCommand( $sql);
//  如果需要,此 SQL 語句可通過如下方式修改:
// $command->text=$newSQL;

$rowCount= $command->execute();    //  執行無查詢 SQL
$dataReader= $command->query();    //  執行一個 SQL 查詢
$rows= $command->queryAll();       //  查詢並返回結果中的所有行
$row= $command->queryRow();        //  查詢並返回結果中的第一行
$column= $command->queryColumn();  //  查詢並返回結果中的第一列
$value= $command->queryScalar();   //  查詢並返回結果中第一行的第一個字段

 

3.獲取查詢結果

 

$dataReader= $command->query();
//  重復調用 read() 直到它返回 false
while(( $row= $dataReader->read())!== false) { ... }
//  使用 foreach 遍歷數據中的每一行
foreach( $dataReader  as  $row) { ... }
//  一次性提取所有行到一個數組
$rows= $dataReader->readAll();

 

4.使用事務

 

$transaction= $connection->beginTransaction();
try
{
     $connection->createCommand( $sql1)->execute();
     $connection->createCommand( $sql2)->execute();
     // .... other SQL executions
     $transaction->commit();
}
catch( Exception  $e//  如果有一條查詢失敗,則會拋出異常
{
     $transaction->rollBack();
}

 

5.綁定列

綁定列可以讓當前查詢結果和一個變量綁定,方便操作。

 

$sql="SELECT username, email FROM tbl_user";
$dataReader= $connection->createCommand( $sql)->query();
//  使用 $username 變量綁定第一列 (username)
$dataReader->bindColumn(1, $username);
//  使用 $email 變量綁定第二列 (email)
$dataReader->bindColumn(2, $email);
while( $dataReader->read()!== false)
{
     //  $username 和 $email 含有當前行中的 username 和 email
}

 

三、參考文章:

1. 數據訪問對象(DAO):http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.dao

2.Active Record:http://www.yiiframework.com/doc/guide/1.1/en/database.ar

3.PHP Yii 框架的數據庫操作筆記一、查詢,更新,刪除的方法(AR模式):http://hi.baidu.com/caoxin_rain/item/df9da2362d6038342f0f8161

4.Yii AR Model 查詢:http://www.cnblogs.com/likwo/archive/2011/09/01/2162017.html

 本文用 菊子曰發布


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM