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

Yii2 Active Record 模式完整實戰:從資料庫配置到 GII 代碼生成

     編輯:PHP 相關知識

Yii2 Active Record 模式完整實戰:從資料庫配置到 GII 代碼生成

Active Record 是 Yii2 核心 ORM 模式,將資料表映射為類,記錄映射為對象。本文完整演示從資料庫配置、GII 代碼生成、遷移管理到常用查詢操作的全流程。

一、資料庫配置

<?php
// config/db.php
return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=localhost;dbname=yii2app',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8mb4',
    // 生產環境建議開啟
    'enableSchemaCache' => true,
    'schemaCacheDuration' => 3600,
    'schemaCache' => 'cache',
];

二、GII 代碼生成器實戰

  1. 訪問 https://yourdomain/index.php?r=gii
  2. Model Generator:
    • Table Name: user 或 * 生成所有
    • Model Class: 自動生成或自定義
    • Namespace: app\models
    • 勾選「Generate Relations」「Enable I18N」
  3. CRUD Generator:
    • Model Class: app\models\User
    • Search Model Class: app\models\UserSearch
    • Controller Class: app\controllers\UserController
    • View Path: @app/views/user

三、資料庫遷移管理

<?php
// 執行:./yii migrate/create create_user_table
// 文件:console/migrations/m240101_000001_create_user_table.php

use yii\db\Migration;

class m240101_000001_create_user_table extends Migration {
    public function safeUp() {
        $this->createTable('{{%user}}', [
            'id' => $this->primaryKey(),
            'username' => $this->string(50)->notNull()->unique(),
            'email' => $this->string(100)->notNull()->unique(),
            'password_hash' => $this->string(255)->notNull(),
            'auth_key' => $this->string(32)->notNull(),
            'status' => $this->smallInteger()->notNull()->defaultValue(10),
            'created_at' => $this->integer()->notNull(),
            'updated_at' => $this->integer()->notNull(),
        ], 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci');
        
        $this->createIndex('idx_user_status', '{{%user}}', 'status');
    }

    public function safeDown() {
        $this->dropTable('{{%user}}');
    }
}

修改表結構遷移

<?php
// ./yii migrate/create add_profile_to_user_table
class m240102_000001_add_profile_to_user_table extends Migration {
    public function safeUp() {
        $this->addColumn('{{%user}}', 'avatar', $this->string(255)->defaultValue(''));
        $this->addColumn('{{%user}}', 'bio', $this->text());
    }
    public function safeDown() {
        $this->dropColumn('{{%user}}', 'avatar');
        $this->dropColumn('{{%user}}', 'bio');
    }
}

執行遷移命令

# 升級
./yii migrate
./yii migrate/up 3        # 升級 3 步
./yii migrate/to m240101  # 升級到指定版本

# 回滾
./yii migrate/down        # 回滾 1 步
./yii migrate/down 3      # 回滾 3 步

四、Active Record 模型最佳實踐

<?php
namespace app\models;

use Yii;
use yii\db\ActiveRecord;
use yii\behaviors\TimestampBehavior;
use yii\behaviors\BlameableBehavior;

class User extends ActiveRecord {
    public static function tableName() {
        return '{{%user}}';
    }

    public function behaviors() {
        return [
            TimestampBehavior::class,     // 自動填充 created_at/updated_at
            BlameableBehavior::class,     // 自動填充 created_by/updated_by
        ];
    }

    public function rules() {
        return [
            [['username', 'email', 'password_hash'], 'required'],
            [['username', 'email'], 'string', 'max' => 100],
            [['username', 'email'], 'unique'],
            ['status', 'in', 'range' => [0, 10, 20]],
        ];
    }

    // 關聯關係
    public function getPosts() {
        return $this->hasMany(Post::class, ['author_id' => 'id']);
    }
    
    public function getProfile() {
        return $this->hasOne(Profile::class, ['user_id' => 'id']);
    }

    // 範圍查詢
    public function scopeActive($query) {
        return $query->andWhere(['status' => 10]);
    }
}

五、常用查詢操作速查

<?php
// 1. 單條記錄
User::findOne(1);
User::findOne(['email' => 'test@example.com']);
User::find()->where(['status' => 10])->one();

// 2. 多條記錄
User::findAll([1, 2, 3]);
User::findAll(['status' => 10]);
User::find()->active()->orderBy('created_at DESC')->limit(10)->all();

// 3. 條件構建
User::find()->where(['>', 'age', 18])
    ->andWhere(['status' => 10])
    ->orWhere(['role' => 'admin'])
    ->all();

// 4. 聚合查詢
User::find()->count();
User::find()->where(['status' => 10])->count();
User::find()->max('age');
User::find()->sum('balance');
User::find()->average('score');

// 5. 關聯預載入(解決 N+1 問題)
$users = User::find()->with('posts', 'profile')->all();
foreach ($users as $user) {
    echo $user->profile->bio; // 不會產生額外查詢
}

// 6. 連表查詢
$users = User::find()
    ->select(['user.*', 'profile.bio'])
    ->innerJoin('{{%profile}}', 'profile.user_id = user.id')
    ->where(['user.status' => 10])
    ->asArray()
    ->all();

// 7. 批量處理(大數據集)
foreach (User::find()->batch(100) as $users) {
    // 每次處理 100 條
    foreach ($users as $user) { ... }
}

// 8. 新增/更新/刪除
$user = new User();
$user->username = 'newuser';
$user->email = 'new@test.com';
$user->setPassword('secret');
$user->generateAuthKey();
$user->save(); // INSERT

$user->status = 20;
$user->save(); // UPDATE

$user->delete(); // DELETE

// 9. 批量插入
Yii::$app->db->createCommand()->batchInsert('{{%user}}', 
    ['username', 'email', 'status'], 
    [['u1', 'u1@test.com', 10], ['u2', 'u2@test.com', 10]]
)->execute();

六、進階技巧

  • 樂觀鎖:添加 version 欄位,配合 OptimisticLockBehavior
  • 軟刪除:使用 SoftDeleteBehavior 或手動添加 deleted_at 篩選
  • 只讀模型:User::find()->asArray()->all() 返回純數組,性能更好
  • 事務操作:Yii::$app->db->transaction(function() { ... });

遵循「遷移管理結構、GII 生成基礎代碼、模型封裝業務邏輯」的工作流,能構建可維護、高性能的數據訪問層。

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