Yii 的查詢生成器提供物件導向方式撰寫 SQL,支援鏈式呼叫、參數綁定、資料庫抽象化,能有效預防 SQL Injection 並簡化跨資料庫遷移。本文系統整理其核心用法,包含資料查詢、資料操作、Schema 管理與進階技巧。
// 取得查詢指令物件
$command = Yii::$app->db->createCommand();
// 方法鏈式建構 SELECT 查詢
$users = $command->select(['id', 'username', 'email'])
->from('user')
->where(['status' => 1])
->orderBy('created_at DESC')
->limit(10)
->queryAll();
| 方法 | 說明 | 範例 |
|---|---|---|
| select() | 指定 SELECT 欄位 | select(['id', 'name']) 或 select('id, name') |
| selectDistinct() | SELECT DISTINCT | selectDistinct('category_id') |
| from() | 指定資料表 | from('user u') 或 from(['u' => 'user']) |
| where() | WHERE 條件(字串或陣列格式) | 見下方詳細說明 |
| andWhere() / orWhere() | 追加 AND/OR 條件 | andWhere(['>', 'age', 18]) |
| join() / leftJoin() / rightJoin() | 各類 JOIN | leftJoin('profile p', 'p.user_id = u.id') |
| groupBy() | GROUP BY | groupBy('department_id') |
| having() | HAVING 條件 | having(['>', 'count(*)', 5]) |
| orderBy() | ORDER BY | orderBy(['name' => SORT_ASC, 'id' => SORT_DESC]) |
| limit() / offset() | 分頁 LIMIT/OFFSET | limit(20)->offset(40) |
| union() | UNION 合併查詢 | union('SELECT * FROM archive_user') |
// 簡單比較
['status' => 1] // WHERE status = 1
['>', 'age', 18] // WHERE age > 18
// 邏輯組合
['and', 'id=1', ['or', 'id=2', 'id=3']] // WHERE id=1 AND (id=2 OR id=3)
// IN / NOT IN
['in', 'id', [1, 2, 3]] // WHERE id IN (1,2,3)
['not in', 'status', [0, -1]] // WHERE status NOT IN (0,-1)
// LIKE
['like', 'name', '%test%'] // WHERE name LIKE '%test%'
['or like', 'tags', ['%php%', '%yii%']] // WHERE tags LIKE '%php%' OR tags LIKE '%yii%'
// 子查詢支援
['in', 'user_id', (new Query())->select('id')->from('admin')]
// 取得單行(陣列) $user = $command->queryOne(); // 取得所有行(陣列集合) $users = $command->queryAll(); // 取得單一欄位值 $count = $command->queryScalar(); // 取得單一欄位陣列 $ids = $command->queryColumn(); // 取得原始 SQL(除錯用) $sql = $command->getRawSql(); // 含參數綁定後的完整 SQL $params = $command->params; // 參數陣列
以下方法會直接建構並執行 SQL,回傳影響列數。
// INSERT
$command->insert('user', [
'username' => 'john',
'email' => 'john@example.com',
'created_at' => time(),
])->execute();
// 批次插入
$command->batchInsert('user', ['username', 'email'], [
['alice', 'alice@example.com'],
['bob', 'bob@example.com'],
])->execute();
// UPDATE
$command->update('user', ['status' => 1], 'id = 1')->execute();
// DELETE
$command->delete('user', 'id = 1')->execute();
提供跨資料庫的結構管理介面,支援抽象資料型別自動對應。
| 方法 | 說明 |
|---|---|
| createTable() | 建立資料表 |
| dropTable() | 刪除資料表 |
| renameTable() | 重新命名資料表 |
| truncateTable() | 清空資料表 |
| addColumn() / dropColumn() / renameColumn() / alterColumn() | 欄位增刪改 |
| addPrimaryKey() / dropPrimaryKey() | 主鍵管理 |
| addForeignKey() / dropForeignKey() | 外鍵管理 |
| createIndex() / dropIndex() | 索引管理 |
pk → int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY (MySQL)string → varchar(255)text → textinteger → int(11)boolean → tinyint(1)dateTime → datetimedecimal → decimalmoney → decimal(19,4)$command->createTable('post', [
'id' => 'pk',
'title' => 'string NOT NULL',
'content' => 'text',
'author_id' => 'integer NOT NULL',
'status' => 'boolean DEFAULT 0',
'created_at' => 'dateTime',
], 'ENGINE=InnoDB CHARSET=utf8mb4')->execute();
reset() 清除前一個查詢狀態,避免條件殘留。$command->select = ['id', 'name'],或建構時傳陣列 createCommand(['select' => ..., 'from' => ...])。createCommand('SELECT * FROM user')->where(...) 不會生效。new \yii\db\Expression('NOW()')。Yii 查詢生成器以鏈式 API、參數綁定、抽象型別三大特性,讓資料庫操作更安全、可維護、可移植。掌握其核心方法與陣列條件格式,能大幅提升開發效率並減少錯誤。