首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Drupal 7 數據庫操作 API 完全指南:查詢構建器最佳實踐

     編輯:PHP 相關知識

Drupal 7 引入強大的資料庫抽象層,提供統一的查詢構建器,支援 MySQL、PostgreSQL、SQLite 等多種驅動,實現「寫一次,跑 everywhere」。本文匯總核心 CRUD 操作與進階用法。

核心優勢

  • **SQL 注入防護**:佔位符自動轉義
  • **跨資料庫兼容**:驅動層自動處理語法差異
  • **可讀性/維護性**:鏈式調用替代原始 SQL 字符串拼接
  • **可擴展性**:支持表達式、子查詢、連接、鎖定等高級特性

基礎 CRUD 操作

1. 插入單條記錄

db_insert('users')
  ->fields([
    'name'  => 'john',
    'mail'  => 'john@example.com',
    'status' => 1,
    'created' => REQUEST_TIME,
  ])
  ->execute(); // 返回自增 ID

2. 批量插入多條記錄

$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();

3. 更新記錄

db_update('users')
  ->condition('uid', 123)
  ->fields([
    'mail' => 'new@example.com',
    'login' => REQUEST_TIME,
  ])
  ->execute(); // 返回影響行數

4. 刪除記錄

db_delete('users')
  ->condition('status', 0)
  ->condition('last_login', REQUEST_TIME - 3600*24*365, '<')
  ->execute();

5. Merge (Upsert):存在則更新,否則插入

db_merge('user_profiles')
  ->key(['uid' => 123]) // 唯一鍵判斷
  ->insertFields([
    'uid' => 123,
    'timezone' => 'Asia/Shanghai',
    'created' => REQUEST_TIME,
  ])
  ->updateFields([
    'timezone' => 'Asia/Shanghai',
    'updated' => REQUEST_TIME,
  ])
  ->execute();

進階查詢技巧

6. 字段自增/表達式更新

// 計數器 +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();

7. 查詢別名與字段選擇

$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');

8. 連接查詢

$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();

9. 子查詢

$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 7 遷移到 8/9/10 注意

  • 服務容器注入:\Drupal::database() 替代全局 db_*()
  • 查詢構建器類名變更:\Drupal\Core\Database\Query\Insert 等
  • 佔位符統一為 :name 命名風格
  • 異步/批次處理改用 Batch API / Queue API

熟練掌握 Drupal DB API,是構建高性能、安全、可維護 Drupal 模塊的核心技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved