Drupal 7 引入強大的資料庫抽象層,提供統一的查詢構建器,支援 MySQL、PostgreSQL、SQLite 等多種驅動,實現「寫一次,跑 everywhere」。本文匯總核心 CRUD 操作與進階用法。
db_insert('users')
->fields([
'name' => 'john',
'mail' => 'john@example.com',
'status' => 1,
'created' => REQUEST_TIME,
])
->execute(); // 返回自增 ID
$values = [
['name' => 'alice', 'mail' => 'alice@example.com'],
['name' => 'bob', 'mail' => 'bob@example.com'],
];
$query = db_insert('users')->fields(['name', 'mail']);
foreach ($values as $record) {
$query->values($record);
}
$query->execute();
db_update('users')
->condition('uid', 123)
->fields([
'mail' => 'new@example.com',
'login' => REQUEST_TIME,
])
->execute(); // 返回影響行數
db_delete('users')
->condition('status', 0)
->condition('last_login', REQUEST_TIME - 3600*24*365, '<')
->execute();
db_merge('user_profiles')
->key(['uid' => 123]) // 唯一鍵判斷
->insertFields([
'uid' => 123,
'timezone' => 'Asia/Shanghai',
'created' => REQUEST_TIME,
])
->updateFields([
'timezone' => 'Asia/Shanghai',
'updated' => REQUEST_TIME,
])
->execute();
// 計數器 +1
db_update('node_counter')
->expression('totalcount', 'totalcount + 1')
->condition('nid', 456)
->execute();
// 複雜表達式
db_update('products')
->expression('price', 'price * (1 + :rate)', [':rate' => 0.1])
->condition('category', 'electronics')
->execute();
$query = db_select('node', 'n');
$query->addField('n', 'title', 'node_title'); // 別名
$query->addField('n', 'nid');
$query->condition('n.type', 'article');
$result = $query->execute()->fetchAllAssoc('nid');
$query = db_select('node', 'n');
$query->join('users', 'u', 'n.uid = u.uid');
$query->fields('n', ['nid', 'title']);
$query->fields('u', ['name', 'mail']);
$query->condition('n.status', 1);
$results = $query->execute()->fetchAll();
$subquery = db_select('node', 'n2');
$subquery->addField('n2', 'nid');
$subquery->condition('n2.type', 'page');
$query = db_select('node', 'n');
$query->condition('n.nid', $subquery, 'IN');
$query->fields('n', ['nid', 'title']);
$transaction = db_transaction();
try {
db_insert('table1')->fields([...])->execute();
db_update('table2')->fields([...])->execute();
$transaction->commit();
} catch (Exception $e) {
$transaction->rollback();
watchdog_exception('mymodule', $e);
}
| 陷阱 | 正確做法 |
|---|---|
| 直接拼接 SQL 字符串 | 始終使用佔位符 :name、%s、%d |
忘記表前綴 {table} | 所有表名用大括號包裹,自動加前綴 |
大數據集用 fetchAll() 導致 OOM | 用 fetchAllAssoc()、fetchCol() 或分批游標 |
| 條件值未轉義 | condition() 自動處理,勿手動 db_escape() |
| 複雜查詢不加索引 | hook_schema() 定義 indexes/unique keys |
\Drupal::database() 替代全局 db_*()\Drupal\Core\Database\Query\Insert 等:name 命名風格熟練掌握 Drupal DB API,是構建高性能、安全、可維護 Drupal 模塊的核心技能。