數據庫之DAO

吐血的事情發生了,寫了一半,網頁死了,還沒草稿。之前翻了一大堆,也不想翻了,都是介紹DAO的一些基本知識。

跳過之前翻的,繼續

1.2 執行SQL語句

數據庫的連接建立好以後,SQL語句就可以通過CDbCommand來執行。我們可以通過調用CDbConnection::createCommand()來實例化一個CDbCommand:

  1. $connection=Yii::app()->db; // assuming you have configured a "db" connection  
  2. // If not, you may explicitly create a connection:  
  3. // $connection=new CDbConnection($dsn,$username,$password);  
  4. $command=$connection->createCommand($sql);  
  5. // if needed, the SQL statement may be updated as follows:  
  6. // $command->text=$newSQL; 

一個SQL語句,通過調用CDbCommand後,有兩種執行方式:

●execute(): 執行一個非查詢語句,例如INSERT, UPDATE and DELETE 。

●query(): 執行一個有返回數據集的SQL語句,例如SELECT。如果成功,返回一個CDbDataReader的實例,可以遍歷所有的查詢返回記錄。爲了便捷各位代碼,Yii也提供了一些諸如queryXXX()的方法,可以直接返回查詢的結果。

SQL在執行的過程中如果出錯的話,會拋出一些異常錯誤。

  1. $rowCount=$command->execute(); // execute the non-query SQL  
  2. $dataReader=$command->query(); // execute a query SQL  
  3. $rows=$command->queryAll(); // query and return all rows of result  
  4. $row=$command->queryRow(); // query and return the first row of result  
  5. $column=$command->queryColumn(); // query and return the first column of result  
  6. $value=$command->queryScalar(); // query and return the first field in the first row 

 1.3 獲取查詢結果

在CDbCommand::query() 實例化了CDbDataReader後,我們可以通過CDbDataReader::read()來讀取數據,也可以使用PHP來一條一條的讀取。

  1. $dataReader=$command->query();  
  2. // calling read() repeatedly until it returns false  
  3. while(($row=$dataReader->read())!==false) f ... g  
  4. // using foreach to traverse through every row of data  
  5. foreach($dataReader as $row) f ... g  
  6. // retrieving all rows at once in a single array  
  7. $rows=$dataReader->readAll(); 

注意,跟query()不一樣的地方,queryXXX() 方法所返回的,是數據本書。例如,queryRow()返回符合查詢條件的第一個記錄的數組。

1.4 事務的使用

當一個應用執行批量的增刪查改的時候,很重要的一點,要保證所有操作都完成,而不是某些操作被完成。這個就是事務,具體還不瞭解數據庫事務的另外找資料補習一下。在Yii當中,CDbTransaction就是用來做事務處理的:

●Begin the transaction.
●逐條的執行SQL語句,任何對數據庫的更新操作,對外部來說都是不可見的。
●提交事務。如果成功的話,更新的數據對外就可見了。
●如果其中的某個操作失敗,則整個事務回滾。

以上的工作流,用代碼表現就是:

  1. $transaction=$connection->beginTransaction();  
  2. try  
  3. {  
  4.     $connection->createCommand($sql1)->execute();  
  5.     $connection->createCommand($sql2)->execute();  
  6.     //.... other SQL executions  
  7.     $transaction->commit();  
  8. }  
  9. catch(Exception $e// an exception is raised if a query fails  
  10. {  
  11.     $transaction->rollBack();  

1.5 參數綁定

爲了防止SQL注入,以及優化SQL語句,我們可以用變量的方式來寫SQL語句。這個變量佔位符可以是命名的(變量),也可以是未命名的(問號)。通過調用CDbCommand::bindParam() 或者是CDbCommand::bindValue()來替換這些佔位符。參數不用引號,底層數據庫會提供這些。在SQL語句執行之前,參數綁定就必須先完成了。

  1. // an SQL with two placeholders ":username" and ":email"  
  2. $sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";  
  3. $command=$connection->createCommand($sql);  
  4. // replace the placeholder ":username" with the actual username value  
  5. $command->bindParam(":username",$username,PDO::PARAM_STR);  
  6. // replace the placeholder ":email" with the actual email value  
  7. $command->bindParam(":email",$email,PDO::PARAM_STR);  
  8. $command->execute();  
  9. // insert another row with a new set of parameters  
  10. $command->bindParam(":username",$username2,PDO::PARAM_STR);  
  11. $command->bindParam(":email",$email2,PDO::PARAM_STR);  
  12. $command->execute(); 

bindParam() 和bindValue()這兩個方法非常的相似,唯一的區別在於:前者綁定的是PHP的變量,後者綁定的是值。當變量的值是一個大的數據塊時,前者看起來就好多了。

有關更多的參數綁定,可以參考PHP的相關文檔。

1.6 列綁定

當我們要獲取查詢結果的時候,也可以採用綁定PHP變量的方法。綁定以後,PHP變量會自動的獲取到當前的記錄集所對應的列值。

  1. $sql="SELECT username, email FROM tbl user";  
  2. $dataReader=$connection->createCommand($sql)->query();  
  3. // bind the 1st column (username) with the $username variable  
  4. $dataReader->bindColumn(1,$username);  
  5. // bind the 2nd column (email) with the $email variable  
  6. $dataReader->bindColumn(2,$email);  
  7. while($dataReader->read()!==false)  
  8. {  
  9.     // $username and $email contain the username and email in the current row  

1.7 使用表前綴

Yii集成了表前綴的使用。表前綴意思就是在當前的數據庫連接中,每個表的其實都是相同的一個字符串,一般是在共享主機的環境中(也就是說一個數據庫,有多個應用工程)。例如,一個工程用tbl_作爲前綴,而另外的一個工程則用yii_作爲前綴。

要啓用表前綴,配置CDbConnection::tablePrefix的屬性就可以了。然後在SQL語句中,用`TableName`來做表名,這裏的TableName就不需要前綴了。例如,數據庫中有一個表,名爲tbl_user,我們把tbl_作爲表前綴,配置好以後,我就可以用以下的代碼來查詢這個表了。

  1. $sql='SELECT * FROM ffusergg';  
  2. $users=$connection->createCommand($sql)->queryAll(); 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章