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

Yii 2.0 資料庫操作完整指南:DAO 配置、查詢建構器與事務處理

     編輯:PHP 相關知識

Yii DAO 核心架構

Yii 的資料庫存取物件 (DAO) 建構在 PHP PDO 之上,提供統一的 API 支援多種資料庫系統 (MySQL、PostgreSQL、SQLite、Oracle、MSSQL 等)。核心組件包括:

  • Connection:管理資料庫連線與交易
  • Command:執行 SQL 語句與參數綁定
  • QueryBuilder:動態建構 SQL 查詢
  • ActiveRecord:ORM 模式,將資料表映射為模型類

資料庫連線配置

基本配置 (config/web.php)

return [
    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=mydatabase',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
            // 可選:表前綴
            'tablePrefix' => 'tbl_',
            // 可選:連線後自動執行 SQL
            'on afterOpen' => function($event) {
                $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
            },
        ],
    ],
];

多資料庫支援

'components' => [
    'db' => [ /* 主資料庫配置 */ ],
    'secondDb' => [
        'class' => 'yii\db\Connection',
        'dsn' => 'sqlite:/path/to/database/file',
    ],
],

使用方式:\Yii::$app->db (主庫)、\Yii::$app->secondDb (次庫)。

獨立連線 (非組件模式)

$connection = new \yii\db\Connection([
    'dsn' => $dsn,
    'username' => $username,
    'password' => $password,
]);
$connection->open();

SQL 執行與參數綁定

基本查詢方法

$connection = \Yii::$app->db;
// 查詢單行
$row = $connection->createCommand('SELECT * FROM user WHERE id=1')->queryOne();
// 查詢多行
$rows = $connection->createCommand('SELECT * FROM user')->queryAll();
// 查詢單一值
$count = $connection->createCommand('SELECT COUNT(*) FROM user')->queryScalar();
// 查詢單一欄位
$names = $connection->createCommand('SELECT name FROM user')->queryColumn();

參數綁定 (防 SQL 注入)

// 單次查詢
$command = $connection->createCommand('SELECT * FROM post WHERE id=:id');
$command->bindValue(':id', $_GET['id']);
$post = $command->queryOne();

// 重複執行 (效能較佳)
$command = $connection->createCommand('DELETE FROM post WHERE id=:id');
$command->bindParam(':id', $id);
$id = 1; $command->execute();
$id = 2; $command->execute();

資料操作便利方法

// INSERT
$connection->createCommand()->insert('user', [
    'name' => 'Sam',
    'age' => 30,
])->execute();

// 批次 INSERT
$connection->createCommand()->batchInsert('user', ['name', 'age'], [
    ['Tom', 30], ['Jane', 20], ['Linda', 25],
])->execute();

// UPDATE
$connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();

// DELETE
$connection->createCommand()->delete('user', 'status = 0')->execute();

表名/欄位名安全引用

使用雙大括號語法自動處理引用與表前綴:

// 自動引用欄位名與表名
$sql = "SELECT COUNT($column) FROM {{table}}";
$rowCount = $connection->createCommand($sql)->queryScalar();

// 支援表前綴 (需配置 tablePrefix)
$sql = "SELECT COUNT($column) FROM {{%$table}}";
// 若 tablePrefix='tbl_',實際查詢 tbl_table

或使用物件方法:$connection->quoteTableName($table)、$connection->quoteColumnName($column)。

交易處理

基本交易

$transaction = $connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();
    $connection->createCommand($sql2)->execute();
    $transaction->commit();
} catch (\Exception $e) {
    $transaction->rollBack();
    throw $e;
}

巢狀交易 (需資料庫支援 Savepoints)

$transaction1 = $connection->beginTransaction();
try {
    // 外層操作
    $transaction2 = $connection->beginTransaction();
    try {
        // 內層操作
        $transaction2->commit();
    } catch (\Exception $e) {
        $transaction2->rollBack();
    }
    $transaction1->commit();
} catch (\Exception $e) {
    $transaction1->rollBack();
}

隔離級別設定

Yii 提供常數對應標準隔離級別:

  • Transaction::READ_UNCOMMITTED
  • Transaction::READ_COMMITTED
  • Transaction::REPEATABLE_READ
  • Transaction::SERIALIZABLE
$transaction = $connection->beginTransaction([
    'isolationLevel' => \yii\db\Transaction::SERIALIZABLE
]);

注意:MSSQL、SQLite 需在連線層級設定隔離級別;PostgreSQL 需在交易開始後呼叫 setIsolationLevel()。

主從複寫與讀寫分離

一主多從配置

'db' => [
    'class' => 'yii\db\Connection',
    'dsn' => 'dsn for master',
    'username' => 'master',
    'password' => '',
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [PDO::ATTR_TIMEOUT => 10],
    ],
    'slaves' => [
        ['dsn' => 'dsn for slave 1'],
        ['dsn' => 'dsn for slave 2'],
    ],
]

框架自動將 SELECT 導向從庫,INSERT/UPDATE/DELETE 導向主庫。可用 $db->useMaster() 強制讀主庫,或設定 enableSlaves=false 關閉分離。

多主多從配置

'masters' => [
    ['dsn' => 'master 1'], ['dsn' => 'master 2'],
],
'slaves' => [ /* 從庫陣列 */ ],

交易預設使用主庫連線;若需在從庫執行交易,呼叫 $db->slave->beginTransaction()。

資料庫 Schema 操作

獲取 Schema 資訊

$schema = $connection->getSchema();
$tables = $schema->getTableNames(); // 所有表名
$columns = $schema->getTableSchema('user')->columns; // 欄位資訊

修改 Schema (Migration 風格 API)

// 建立表
$connection->createCommand()->createTable('post', [
    'id' => 'pk',
    'title' => 'string',
    'text' => 'text',
])->execute();

// 刪除表
$connection->createCommand()->dropTable('post')->execute();

// 新增欄位
$connection->createCommand()->addColumn('post', 'author_id', 'integer')->execute();

ActiveRecord 查詢範例

// 主鍵查詢
$customer = Customer::findOne(10);
$customers = Customer::findAll([10, 11, 12]);

// 條件查詢
$customers = Customer::find()
    ->where(['age' => 30, 'status' => 1])
    ->andWhere('score > 100')
    ->orderBy('id DESC')
    ->limit(10)
    ->offset(5)
    ->all();

// 參數綁定
$customers = Customer::find()
    ->where('age=:age AND status=:status')
    ->addParams([':age' => 30, ':status' => 1])
    ->all();

// 原生 SQL
$customers = Customer::findBySql('SELECT * FROM customer WHERE age=30')->all();

// 更新/刪除
Customer::updateAll(['status' => 1], 'id = :id', [':id' => 10]);
Customer::deleteAll(['status' => 1], 'id = :id', [':id' => 10]);

子查詢支援

$subQuery = (new \yii\db\Query())
    ->select('COUNT(*)')
    ->from('customer');

$query = (new \yii\db\Query())
    ->select(['id', 'count' => $subQuery])
    ->from('customer');

總結

Yii DAO 提供從底層 SQL 執行到高階 ActiveRecord 的完整資料庫操作體系。掌握參數綁定、交易控制、主從分離與 Schema 管理,能構建安全、高效、可擴展的資料存取層。實務上建議:簡單查詢用 DAO/QueryBuilder,複雜業務邏輯用 ActiveRecord,結構變更用 Migration。

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