Yii DAO (Data Access Object) 建立在 PHP PDO 之上,提供統一的 API 訪問 MySQL、PostgreSQL、SQL Server、Oracle 等多種數據庫。應用層代碼無需修改即可切換底層 DBMS。使用前需確保安裝 PDO 擴展及對應驅動(如 pdo_mysql)。
| 類名 | 職責 |
|---|---|
CDbConnection | 代表數據庫連接,管理連接生命週期 |
CDbCommand | 封裝 SQL 語句,提供執行、查詢、參數綁定方法 |
CDbDataReader | 只進游標,用於逐行讀取大結果集,節省內存 |
CDbTransaction | 事務控制,保證多條 SQL 的原子性 |
// 獨立使用
$conn = new CDbConnection($dsn, $user, $pass);
$conn->active = true;
// ... 操作
$conn->active = false;
// 作為應用組件配置 (main.php)
'db' => array(
'class' => 'CDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=testdb',
'username' => 'root',
'password' => 'password',
'emulatePrepare' => true,
),
// 之後全局通過 Yii::app()->db 訪問,自動激活
常用 DSN 格式:
mysql:host=localhost;dbname=testdbsqlite:/path/to/dbfilepgsql:host=localhost;port=5432;dbname=testdb$cmd = Yii::app()->db->createCommand($sql);
// 非查詢:INSERT/UPDATE/DELETE,返回影響行數
$rowCount = $cmd->execute();
// 查詢:返回 CDbDataReader
$reader = $cmd->query();
// 便捷方法
$rows = $cmd->queryAll(); // 所有行
$row = $cmd->queryRow(); // 第一行
$col = $cmd->queryColumn(); // 第一列
$val = $cmd->queryScalar(); // 單一值
$reader = $cmd->query();
// 方式一:while 循環
while (($row = $reader->read()) !== false) { /* ... */ }
// 方式二:foreach 遍歷
foreach ($reader as $row) { /* ... */ }
// 方式三:一次性取出所有
$rows = $reader->readAll();
$tx = $conn->beginTransaction();
try {
$conn->createCommand($sql1)->execute();
$conn->createCommand($sql2)->execute();
$tx->commit();
} catch (Exception $e) {
$tx->rollBack();
}
$sql = "INSERT INTO tbl_user (username, email) VALUES (:username, :email)";
$cmd = $conn->createCommand($sql);
$cmd->bindParam(":username", $username, PDO::PARAM_STR);
$cmd->bindParam(":email", $email, PDO::PARAM_STR);
$cmd->execute();
// 重複執行只需重新綁定新值
$cmd->bindParam(":username", $username2);
$cmd->bindParam(":email", $email2);
$cmd->execute();
bindParam 綁定變量引用,適合大數據;bindValue 綁定具體值。
$reader = $conn->createCommand("SELECT username, email FROM tbl_user")->query();
$reader->bindColumn(1, $username);
$reader->bindColumn(2, $email);
while ($reader->read() !== false) {
// $username, $email 自動更新為當前行數據
}
配置 CDbConnection::tablePrefix = 'tbl_',SQL 中使用 {{TableName}}(如 {{user}} 代表 tbl_user),便於多應用共享數據庫。
CDbDataReader 流式讀取,避免內存溢出。