CDbConnection:連線管理、交易控制CDbCommand:SQL 執行、參數綁定CDbDataReader:前向唯讀游標CDbTransaction:交易物件使用 Chinook 資料庫 Employee 表,欄位:EmployeeId, LastName, FirstName, Title, ReportsTo, BirthDate, HireDate, Address, City, State, Country, PostalCode, Phone, Fax, Email。
// 方式一:獨立連線 (短連線)
$connection = new CDbConnection(
'mysql:host=localhost;dbname=chinook',
'root',
'password'
);
$connection->active = true; // 開啟連線
// ... 操作
$connection->active = false; // 關閉連線
// 方式二:應用組件連線 (推薦,單例共享)
// main.php 已配置 'db' 組件
$connection = Yii::app()->db; // 自動連線 (除非 autoConnect=false)
$command = $connection->createCommand($sql);
// 或
$command = $connection->createCommand()
->select('*')
->from('Employee')
->where('EmployeeId=:id', [':id'=>1]);
| 方法 | 回傳 | 適用場景 |
|---|---|---|
| queryAll() | 陣列的陣列 (所有行) | 小結果集完整載入 |
| queryRow() | 單行陣列 | 預期單行結果 |
| queryColumn() | 單欄位值陣列 | 僅需一欄位 |
| queryScalar() | 單一純量值 | COUNT(*), MAX(id) 等 |
| query() | CDbDataReader | 大結果集流式處理 |
// 命名參數
$command = $connection->createCommand(
"SELECT * FROM Employee WHERE LastName=:name AND Country=:country"
);
$command->bindParam(':name', $lastName, PDO::PARAM_STR);
$command->bindParam(':country', $country, PDO::PARAM_STR);
// 或一次綁定
$command->bindValues([':name'=>$lastName, ':country'=>$country]);
// 位置參數
$command = $connection->createCommand(
"INSERT INTO Employee (LastName, FirstName, Email) VALUES (?, ?, ?)"
);
$command->bindValues([$lastName, $firstName, $email]);
$affected = $command->execute(); // 回傳影響行數
// INSERT 後取得自增 ID
$lastId = $connection->getLastInsertId();
$transaction = $connection->beginTransaction();
try {
// 多步操作
$connection->createCommand()->insert('Employee', [
'LastName' => 'Doe',
'FirstName' => 'John',
'Email' => 'john.doe@example.com',
])->execute();
$connection->createCommand()->update('Employee', [
'Title' => 'Senior ' . $oldTitle
], 'EmployeeId=:id', [':id'=>$id])->execute();
$transaction->commit();
} catch (Exception $e) {
$transaction->rollBack();
throw $e;
}
$command = $connection->createCommand('SELECT * FROM Employee');
$reader = $command->query(); // 回傳 CDbDataReader
while ($reader->read()) {
$row = $reader->getAttributes(); // 當前行關聯陣列
// 處理單行,記憶體不累積
processEmployee($row);
}
$reader->close(); // 釋放資源
class SiteController extends CController {
public function actionIndex() {
$model = [];
$connection = Yii::app()->db;
// 參數化查詢
$command = $connection->createCommand()
->select('EmployeeId, FirstName, LastName, Title, Email')
->from('Employee')
->where('ReportsTo IS NULL'); // 最高層主管
$dataReader = $command->query();
foreach ($dataReader as $row) {
$emp = new DataModel();
$emp->employeeId = $row['EmployeeId'];
$emp->firstName = $row['FirstName'];
$emp->lastName = $row['LastName'];
$emp->title = $row['Title'];
$emp->email = $row['Email'];
$model[] = $emp;
}
$this->render('index', ['model' => $model]);
}
}
class DataModel {
public $employeeId;
public $firstName;
public $lastName;
public $title;
public $address;
public $email;
}
queryAll() 佔滿記憶體。CDbException,Controller 層統一捕獲轉友善訊息。Yii::app()->db,避免重複建立連線開銷。