Laravel 雄辩与查询构建器的优缺点

Posted

技术标签:

【中文标题】Laravel 雄辩与查询构建器的优缺点【英文标题】:Laravel eloquent vs query builder pros and cons 【发布时间】:2020-02-07 09:32:30 【问题描述】:

每当我创建一个 laravel 项目时,我总是不仅在模型中而且在数据库中定义关系(我总是使用php artisan make:model ModelName -mcr)。有时我看到他们只在模型中定义关系而不在数据库中定义关系的代码,反之亦然。有人能告诉我他们有什么区别吗?我应该总是在模型和数据库中定义关系,还是应该在其中一个中定义关系?另外,我总是同时使用 laravel eloquent 查询和 laravel 查询生成器 DB::table。两者都使用的优缺点是什么?哪个更快?告诉我你的意见和建议。我希望你明白我的意思。谢谢

示例模型

public function damage()
        return $this->hasMany('App\Product');
    

样本表


        Schema::table('damages', function($table)
        
            $table->foreign('product_id')
                    ->references('id')
                    ->on('products')
                    ->onDelete('cascade');
        );

示例查询

  public function getDamages()
        $damages = DB::select(
            "SELECT damages.product_id, damages.quantity, damages.price, products.product_name
            FROM damages
            JOIN products on damages.product_id = products.id"
           );
        return view('damages', compact('damages'));

//or

 $recipes = DB::table('recipes')
            ->join('category_recipe', 'recipes.id', '=', 'category_recipe.recipe_id')
            ->join('category', 'category.id', '=', 'category_recipe.category_id')
            ->join('users', 'users.id', '=', 'recipes.user_id')
            ->where('category.id', '=', $cat_id)->get(array('recipes.*','users.*'));  

    

示例查询 2

public function index()
       $damage = Damage::all();
//or
       $suppliers = Supplier::all()->where('status', 'active');
//or
       $recipes = Recipe::with('category')->where('category_id',$cat_id)->get();  


【问题讨论】:

这不是两个问题..?您应该在表或 laravel 迁移中定义关系以保持数据库一致性。 eloquent 和 query builder 都是可用且安全的(只要您避免使用带有字符串连接的DB::raw,请使用proper binding)。 我为什么不应该使用DB::raw先生?这很糟糕吗? 如laravel documentation 中所述,请注意DB::raw,因为您可能会不小心在您的网站上允许sql injection,这很糟糕。 哦,我明白了,先生。谢谢你的信息。 【参考方案1】:

根据这篇文章: https://kursuswebprogramming.com/perbedaan-eloquent-dan-query-builder-laravel/

Eloquent ORM 是基于 Query builder 的扩展方法。它发展到 制作一个简单的源代码,让你更快地编写你的代码。但对我来说,它的表达方式太少了,因为你必须将你的模型名称设置为表名。

还有一个关于执行时间的比较:

Eloquent ORM(执行时间:1.41 秒,执行查询:1000)

<?php

Route::get("test",function()
    for($i=0;$i<1000;$i++)
         $t=new Country();
         $t->label=$i." Row";
         $t->save();
    
); 
?>

查询生成器(执行时间:938 毫秒,执行的查询:1000)

<?php
Route::get("test",function()
    for($i=0;$i<1000;$i++)
         DB::table("countries")->insert(["label"=>$i." Row"]);
    
);
?>

这证明 Query Builder 比 Eloquent ORM 快 0.5 秒。

【讨论】:

【参考方案2】:

好吧,选择了答案,但我只是想表明,与 Query Builder 相比,eloquent 并没有那么慢。我们需要的只是技术。

下面的技巧,你的口才快很多。

<?php

Route::get("test",function() 
   $countries = [];
    for($i=0;$i<1000;$i++) 
         $countries[] = [
             'label' => $i . ' Row',
         ];
    
    Country::insert($countries);
); 

Eloquent 是为了可读性而设计的,它牺牲了一点性能,但如果你正确使用它,它不会太多。 对于长期项目,了解导致问题的代码并快速解决问题的能力比 10k 记录查询生成器慢 1 秒更重要。 至少这是我的想法。

【讨论】:

以上是关于Laravel 雄辩与查询构建器的优缺点的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 通过属性获得雄辩的查询构建器关系

雄辩的查询构建器laravel 5.6中的未知列

laravel 雄辩的查询构建器更新自定义时间戳字段而没有任何逻辑

Laravel 雄辩的查询 WhereNotIn 与 WhereNotNull

Laravel 雄辩的 SQL 查询与 OR 和 AND 与 where 子句

Laravel 雄辩的查询与条件下另一个表中的值的总和