Laravel 与 Yii 框架数据库操作指南

概述

本文整合 Laravel 与 Yii 2 框架数据库操作的核心方法、语法差异、逐行对照及错误排查,既覆盖单框架实操,也满足跨框架开发切换需求,适合 PHP 开发者快速上手和灵活适配。

一、Laravel 数据库操作基础

Laravel 提供 Eloquent ORM、查询构造器(DB 门面)、原生 SQL 三种操作方式,兼顾优雅性与灵活性,自动防范 SQL 注入。

1. 数据库配置

配置文件位于 config/database.php,实际开发中通过根目录 .env 文件配置连接信息,框架自动读取覆盖默认值:


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_demo
DB_USERNAME=root
DB_PASSWORD=your_password

2. 核心操作方式

(1)查询构造器(DB 门面,无模型)

无需创建数据表模型,通过 DB 门面直接操作,语法简洁流畅:


use Illuminate\Support\Facades\DB;

// 基础查询
public function index()
{
    $data = DB::table('core_region')
                ->select(['national_code', 'region_name', 'parent_id'])
                ->where('national_code', '<', 110117)
                ->offset(15) // 跳过前15条
                ->limit(10)  // 获取10条
                ->orderBy('national_code', 'desc')
                ->get();
    return $data->toArray(); // 结果转数组
}

(2)Eloquent ORM(模型驱动)

模型与数据表映射,面向对象风格,适合复杂业务逻辑,需在 app/Models 目录创建模型:


// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $table = 'users'; // 手动指定表名(默认模型名复数)
    protected $fillable = ['name', 'email', 'password']; // 允许批量赋值字段
    public $timestamps = true; // 自动维护 created_at/updated_at
}

ORM 基础操作:


use App\Models\User;

// 查询
$user = User::find(1); // 按主键查询,无结果返回null
$users = User::where('status', 1)->orderBy('id', 'desc')->get()->toArray();

// 新增
User::create(['name' => 'test', 'email' => 'test@example.com']);

// 更新
$user->name = 'new name';
$user->save();

// 删除
User::destroy([1,2,3]); // 按主键批量删除

(3)事务处理


// 自动事务(推荐,支持重试次数)
DB::transaction(function () {
    User::create(['name' => 'test']);
    Order::create(['user_id' => 1]);
}, 5); // 死锁时重试5次

// 手动事务
DB::beginTransaction();
try {
    // 业务逻辑
    DB::commit();
} catch (\Exception $e) {
    DB::rollBack();
    throw $e;
}

二、Yii 2 数据库操作基础

Yii 2 以 Active Record(AR)模型为核心,需生成数据表模型,支持查询构建器和原生 SQL,配置化程度高。

1. 数据库配置

配置文件位于 config/db.php


return [
    'class' => 'yii\db\Connection',
    'dsn' => 'mysql:host=127.0.0.1;dbname=yii_demo',
    'username' => 'root',
    'password' => 'your_password',
    'charset' => 'utf8',
];

2. 核心操作方式

(1)Active Record(AR 模型,推荐)

通过 Gii 代码生成器(访问 website/gii)创建模型,继承 yii\db\ActiveRecord,必须关联具体模型文件:


// app/models/ProductCategory.php
namespace app\models;
use yii\db\ActiveRecord;

class ProductCategory extends ActiveRecord
{
    // 必须手动指定表名
    public static function tableName()
    {
        return 'product_category';
    }
}

AR 基础操作:


use app\models\ProductCategory;

// 查询(结果直接转数组)
$list = ProductCategory::find()
            ->select(['category_id', 'category_name'])
            ->where(['level' => 1, 'is_delete' => 0])
            ->asArray() // 前置指定返回数组
            ->all();

// 新增
$category = new ProductCategory();
$category->category_name = '测试分类';
$category->save();

// 更新
ProductCategory::updateAll(['is_delete' => 1], ['category_id' => 1]);

// 删除
$category = ProductCategory::findOne(1);
$category->delete();

(2)查询构建器(无模型)

无模型时需实例化 yii\db\Query 类,语法偏向配置式:


use yii\db\Query;

$query = new Query();
$list = $query->select(['category_id', 'category_name'])
            ->from('product_category')
            ->where(['level' => 1, 'is_delete' => 0])
            ->all();

(3)事务处理


// 自动事务
Yii::$app->db->transaction(function () {
    $user = new User();
    $user->name = 'test';
    $user->save();
});

// 手动事务
$transaction = Yii::$app->db->beginTransaction();
try {
    // 业务逻辑
    $transaction->commit();
} catch (\Exception $e) {
    $transaction->rollBack();
    throw $e;
}

三、Laravel 与 Yii 2 数据库操作核心差异

对比维度 Laravel Yii 2
核心操作方式 1. 主推 Eloquent ORM(面向对象)2. 支持 DB 门面(无模型快捷操作)3. 原生 SQL 需通过 DB::select 执行 1. 主推 Active Record(模型驱动)2. 支持 Query 类(无模型,语法繁琐)3. 原生 SQL 需通过 createCommand 执行
模型依赖与创建 1. Eloquent 模型手动创建,继承 Model 类2. 支持无模型操作,灵活度高 1. AR 模型推荐通过 Gii 生成,继承 ActiveRecord 类2. 强依赖模型,无官方无模型快捷方式
查询结果转数组 后置方法 toArray(),需在查询结果后调用 前置方法 asArray(),查询时指定返回格式
批量赋值控制 强制配置 $fillable/$guarded,否则抛异常,安全性高 通过 rules() 验证规则间接控制,无专门属性,需手动把控
关联模型定义 关联方法名直接映射属性(如 orders() 对应 $user->orders 关联方法需以 getXXX() 命名(如 getOrders()
分页功能 一键生成:paginate(10),视图直接渲染分页链接 需借助 ActiveDataProvider 配置实现完整分页
查询缓存 无内置机制,需手动结合 Cache 门面实现 内置缓存:cache(3600) 方法快速启用
适用场景 中小型项目、快速开发,适合新手和追求优雅语法的团队 中大型项目、高性能需求,适合需精细控制的团队

四、Laravel 与 Yii 2 语法逐行对照表

基于相同业务场景编写,方便跨框架快速切换复制。

业务场景 Laravel 语法 Yii 2 语法
查询所有数据 // Eloquent 方式
use App\Models\User;
$users = User::all()->toArray();
/ DB 门面方式
use Illuminate\Support\Facades\DB;
$users = DB::table('users')->get()->toArray();
// AR 方式
use app\models\User;
$users = User::find()->asArray()->all();
// Query 方式
use yii\db\Query;
$query = new Query();
$users = $query->from('users')->all();
按主键查单条数据 use App\Models\User;
$user = User::find(1)->toArray();
$user = User::findOrFail(1)->toArray();
use app\models\User;
$user = User::findOne(1, ['asArray' => true]);
$user = User::find()->where(['id'=>1])->asArray()->one();
多条件查询 use App\Models\User;
$users = User::where('status', 1)->where('age', '>', 18)->orderBy('id', 'desc')->get()->toArray();
use app\models\User;
$users = User::find()->where(['status'=>1])->andWhere(['>', 'age', 18])->orderBy(['id'=>SORT_DESC])->asArray()->all();
关联查询(用户-订单,一对多) // User 模型定义关联
public function orders(){
return $this->hasMany(Order::class);
}
// 预加载查询
$user = User::with('orders')->find(1);
$orders = $user->orders->toArray();
// User 模型定义关联
public function getOrders(){
  return $this->hasMany(Order::class, 'user_id');
}
// 预加载查询
$user = User::find()->with('orders')->where(['id'=>1])->one();
$orders = $user->orders;
新增数据 use App\Models\User;
// 单条新增
User::create(['name'=>'test', 'email'=>'test@xxx.com']);
// 批量新增
User::insert([  ['name'=>'test1'],['name'=>'test2']]);
use app\models\User;
// 单条新增
$user = new User();
$user->name = 'test';
$user->save();
// 批量新增
Yii::$app->db->createCommand()->batchInsert(  'users',['name'],[['test1'],['test2']])->execute();
批量更新 use App\Models\User;
User::where('status', 1)->update(['status'=>2]);
use app\models\User;
User::updateAll(['status'=>2], ['status'=>1]);
原生 SQL 执行 use Illuminate\Support\Facades\DB;
// 查询
$users = DB::select('select * from users where id = ?', [1]);
// 执行更新
DB::statement('update users set status=1 where id=1');
// 查询
$users = Yii::$app->db->createCommand(  'select * from users where id=:id',[':id'=>1])->queryAll();
// 执行更新
Yii::$app->db->createCommand(  'update users set status=1 where id=1')->execute();

五、常见错误对比排查表

错误现象 Laravel 可能原因及解决方案 Yii 2 可能原因及解决方案
批量赋值失败 未配置 $fillable/$guarded,在模型中添加对应字段即可 未配置 rules() 验证规则,或字段无写入权限,补充规则或检查字段权限
查询结果无法转数组 忘记调用 toArray(),或查询结果为单条对象,需先判断再转换 未添加 asArray() 方法,或查询方式错误,在 find() 后添加该方法
关联查询出现 N+1 问题 未使用 with() 预加载关联,改为 User::with('orders')->get() 同 Laravel,需通过 with() 预加载,避免循环中查询关联
模型找不到对应表 表名不符合默认复数规则,在模型中手动配置 $table 指定表名 未实现tableName() 方法,或方法返回表名错误,补充该方法并校验表名
事务提交/回滚失败 数据库引擎不支持事务(如 MyISAM),改为 InnoDB;或未捕获异常 未实例化 $transaction 对象,或引擎不支持,检查引擎并规范事务写法
分页功能无法正常显示 未在视图中调用 $users->links(),补充分页链接渲染代码 未使用 ActiveDataProvider 配置分页,改用数据提供器实现