本文是YII學習總結系列文章的第二篇,主要向我們介紹了資料存取物件(DAO),十分的詳細,有需要的小夥伴參考下
Yii提供了強大的資料庫程式支援。 Yii資料存取物件(DAO)建立在PHP的資料物件(PDO)extension上,使得在單一的統一的介面可以存取不同的資料庫管理系統(DBMS)。使用Yii的DAO開發的應用程式可以輕鬆切換使用不同的資料庫管理系統,而不需要修改資料存取代碼。
資料存取物件(DAO) 對存取儲存在不同資料庫管理系統(DBMS)中的資料提供了一個通用的API。 因此,在將底層 DBMS 更換為另一個時,無需修改使用了 DAO 存取資料的代碼。
Yii DAO 是基於 PHP Data Objects (PDO) 建構。它是一個為許多流行的DBMS提供統一資料存取的擴展,這些 DBMS 包括 MySQL, PostgreSQL 等等。因此,要使用 Yii DAO,PDO 擴充功能和特定的 PDO 資料庫驅動(例如PDO_MYSQL) 必須安裝。
Yii DAO 主要包含以下四個類別:
CDbConnection: 代表一個資料庫連線。
CDbCommand: 代表一條透過資料庫執行的 SQL 語句。
CDbDataReader: 代表一個只向前移動的,來自一個查詢結果集中的行的流。
CDbTransaction: 代表一個資料庫事務。
下面,我們介紹 Yii DAO 在不同場景中的應用。
1. 建立資料庫連接
要建立一個資料庫連接,建立一個 CDbConnection 實例並將其啟動。 連接到資料庫需要一個資料來源的名字(DSN)以指定連接資訊。使用者名稱和密碼也可能會用到。 當連接到資料庫的過程中發生錯誤時 (例如,錯誤的 DSN 或無效的使用者名稱/密碼),將會拋出一個例外。
程式碼如下:
$connection=new CDbConnection($dsn,$username,$password); // 建立连接。你可以使用 try...catch 捕获可能抛出的异常 $connection->active=true; ...... $connection->active=false; // 关闭连接
DSN 的格式取決於所使用的 PDO 資料庫驅動程式。整體來說, DSN 要含有 PDO 驅動的名字,跟上一個冒號,再跟上驅動特定的連線語法。可查閱 PDO 文件 以取得更多資訊。 下面是一個常用DSN格式的清單。
程式碼如下:
SQLite: sqlite:/path/to/dbfile MySQL: mysql:host=localhost;dbname=testdb PostgreSQL: pgsql:host=localhost;port=5432;dbname=testdb SQL Server: mssql:host=localhost;dbname=testdb Oracle: oci:dbname=//localhost:1521/testdb
由於 CDbConnection 繼承自 CApplicationComponent,我們也可以將其作為一個 應用元件 使用。要這樣做的話, 請在應用程式設定中設定db (或其他名字)應用元件如下:
程式碼如下:
array( ...... 'components'=>array( ...... 'db'=>array( 'class'=>'CDbConnection', 'connectionString'=>'mysql:host=localhost;dbname=testdb', 'username'=>'root', 'password'=>'password', 'emulatePrepare'=>true, // needed by some MySQL installations ), ), )
然後我們就可以透過Yii::app()->db 存取資料庫連線了。它已經被自動啟動了,除非我們特意配置了CDbConnection::autoConnect 為 false。透過這種方式,這個單獨的DB連接就可以在我們程式碼中的許多地方共享。
2. 執行 SQL 語句
資料庫連線建立後,SQL 語句就可以透過使用 CDbCommand 執行了。你可以透過使用指定的SQL語句作為參數來呼叫 CDbConnection::createCommand() 來建立一個 CDbCommand 實例。
程式碼如下:
$connection=Yii::app()->db; // 假设你已经建立了一个 "db" 连接 // 如果没有,你可能需要显式建立一个连接: // $connection=new CDbConnection($dsn,$username,$password); $command=$connection->createCommand($sql); // 如果需要,此 SQL 语句可通过如下方式修改: // $command->text=$newSQL;
一條SQL 語句會透過CDbCommand 以下列兩種方式執行:
execute() : 執行一個無查詢(non-query)SQL語句, 例如INSERT, UPDATE 和DELETE 。如果成功,它將傳回此執行所影響的行數。
query(): 執行一條會傳回若干行資料的 SQL 語句,例如 SELECT。 如果成功,它將傳回一個CDbDataReader 實例,透過此實例可以遍歷資料的結果行。為簡單起見, (Yii)也實作了一系列queryXXX() 方法以直接傳回查詢結果。
執行 SQL 語句時如果發生錯誤,將會拋出例外。
程式碼如下:
$rowCount=$command->execute(); // 执行无查询 SQL $dataReader=$command->query(); // 执行一个 SQL 查询 $rows=$command->queryAll(); // 查询并返回结果中的所有行 $row=$command->queryRow(); // 查询并返回结果中的第一行 $column=$command->queryColumn(); // 查询并返回结果中的第一列 $value=$command->queryScalar(); // 查询并返回结果中第一行的第一个字段
3. 取得查詢結果
在CDbCommand::query() 產生CDbDataReader 實例之後,你可以透過由CDbCommand::query() 產生重複呼叫CDbDataReader::read() 取得結果中的行。你也可以在 PHP 的 foreach 語言結構中使用 CDbDataReader 一行行檢索資料。
程式碼如下:
$dataReader=$command->query(); // 重复调用 read() 直到它返回 false while(($row=$dataReader->read())!==false) { ... } // 使用 foreach 遍历数据中的每一行 foreach($dataReader as $row) { ... } // 一次性提取所有行到一个数组 $rows=$dataReader->readAll();
注意: 不同於 query(), 所有的 queryXXX() 方法會直接傳回資料。 例如, queryRow() 會傳回代表查詢結果第一行的一個陣列。
4. 使用事務
當一個應用要執行幾個查詢,每個查詢要從資料庫中讀取並/或向資料庫寫入資訊時, 保證資料庫沒有留下幾個查詢而只執行了另外幾個查詢是非常重要的。 事務,在 Yii 中表現為 CDbTransaction 實例,可能會在下面的情況中啟動:
開始事務.
一個個執行查詢。任何對資料庫的更新對外界不可見。
提交事務。如果事務成功,更新變為可見。
如果查詢中的一個失敗,整個交易回滾。
上述工作流程可以透過以下程式碼實現:
程式碼如下:
$transaction=$connection->beginTransaction(); try { $connection->createCommand($sql1)->execute(); $connection->createCommand($sql2)->execute(); //.... other SQL executions $transaction->commit(); } catch(Exception $e) // 如果有一条查询失败,则会抛出异常 { $transaction->rollBack(); }
5. 绑定参数
要避免 SQL 注入攻击 并提高重复执行的 SQL 语句的效率, 你可以 "准备(prepare)"一条含有可选参数占位符的 SQL 语句,在参数绑定时,这些占位符将被替换为实际的参数。
参数占位符可以是命名的 (表现为一个唯一的标记) 或未命名的 (表现为一个问号)。调用CDbCommand::bindParam() 或 CDbCommand::bindValue() 以使用实际参数替换这些占位符。 这些参数不需要使用引号引起来:底层的数据库驱动会为你搞定这个。 参数绑定必须在 SQL 语句执行之前完成。
代码如下:
// 一条带有两个占位符 ":username" 和 ":email"的 SQL $sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)"; $command=$connection->createCommand($sql); // 用实际的用户名替换占位符 ":username" $command->bindParam(":username",$username,PDO::PARAM_STR); // 用实际的 Email 替换占位符 ":email" $command->bindParam(":email",$email,PDO::PARAM_STR); $command->execute(); // 使用新的参数集插入另一行 $command->bindParam(":username",$username2,PDO::PARAM_STR); $command->bindParam(":email",$email2,PDO::PARAM_STR); $command->execute();
方法 bindParam() 和 bindValue() 非常相似。唯一的区别就是前者使用一个 PHP 变量绑定参数, 而后者使用一个值。对于那些内存中的大数据块参数,处于性能的考虑,应优先使用前者。
关于绑定参数的更多信息,请参考 相关的PHP文档。
6. 绑定列
当获取查询结果时,你也可以使用 PHP 变量绑定列。 这样在每次获取查询结果中的一行时就会自动使用最新的值填充。
代码如下:
$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 }
7. 使用表前缀
从版本 1.1.0 起, Yii 提供了集成了对使用表前缀的支持。 表前缀是指在当前连接的数据库中的数据表的名字前面添加的一个字符串。 它常用于共享的服务器环境,这种环境中多个应用可能会共享同一个数据库,要使用不同的表前缀以相互区分。 例如,一个应用可以使用 tbl_ 作为表前缀而另一个可以使用 yii_。
要使用表前缀,配置 CDbConnection::tablePrefix 属性为所希望的表前缀。 然后,在 SQL 语句中使用{{TableName}} 代表表的名字,其中的 TableName 是指不带前缀的表名。 例如,如果数据库含有一个名为tbl_user 的表,而 tbl_ 被配置为表前缀,那我们就可以使用如下代码执行用户相关的查询:
代码如下:
$sql='SELECT * FROM {{user}}'; $users=$connection->createCommand($sql)->queryAll();

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

PHP的未來將通過適應新技術趨勢和引入創新特性來實現:1)適應云計算、容器化和微服務架構,支持Docker和Kubernetes;2)引入JIT編譯器和枚舉類型,提升性能和數據處理效率;3)持續優化性能和推廣最佳實踐。

在PHP中,trait適用於需要方法復用但不適合使用繼承的情況。 1)trait允許在類中復用方法,避免多重繼承複雜性。 2)使用trait時需注意方法衝突,可通過insteadof和as關鍵字解決。 3)應避免過度使用trait,保持其單一職責,以優化性能和提高代碼可維護性。

依賴注入容器(DIC)是一種管理和提供對象依賴關係的工具,用於PHP項目中。 DIC的主要好處包括:1.解耦,使組件獨立,代碼易維護和測試;2.靈活性,易替換或修改依賴關係;3.可測試性,方便注入mock對象進行單元測試。

SplFixedArray在PHP中是一種固定大小的數組,適用於需要高性能和低內存使用量的場景。 1)它在創建時需指定大小,避免動態調整帶來的開銷。 2)基於C語言數組,直接操作內存,訪問速度快。 3)適合大規模數據處理和內存敏感環境,但需謹慎使用,因其大小固定。

PHP通過$\_FILES變量處理文件上傳,確保安全性的方法包括:1.檢查上傳錯誤,2.驗證文件類型和大小,3.防止文件覆蓋,4.移動文件到永久存儲位置。

JavaScript中處理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。 1.??返回第一個非null或非undefined的操作數。 2.??=將變量賦值為右操作數的值,但前提是該變量為null或undefined。這些操作符簡化了代碼邏輯,提高了可讀性和性能。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Linux新版
SublimeText3 Linux最新版

SublimeText3漢化版
中文版,非常好用