Laravel 查询构建器与 Raw

Maa*_*per 3 query-builder laravel laravel-5.3

我对 laravel 还很陌生,到目前为止,我真的很喜欢 eloquent 和 querybuilder,但是一旦查询变得更加复杂,我的头就开始受伤了……我在很长一段时间后刚刚完成了 2 个工作示例,也许你们可以提供帮助我优化一下。我先举个例子,然后说(缺点)优点

所以首先是 DB::select... 老实说,我认为它比第二个示例更具可读性。

    $shared_slugs   = Magic::in_query($this->shared_slugs);

    $items = DB::select("
        SELECT * FROM f_admin_items
        WHERE
            active = 1
        AND (
            slug IN $shared_slugs
            OR
            :treshhold <= :urank AND id IN (SELECT admin_item_id FROM f_user_access WHERE user_id = :uid)
            OR
            :treshhold > :urank AND `rank` >= :urank
        )
        ORDER BY `order` ASC
    ", [
        'treshhold' => $this->threshold_rank,
        'urank' => $user_rank,
        'uid'    => $user_id
    ]);
Run Code Online (Sandbox Code Playgroud)

总体而言,使用命名参数绑定非常有效。基本上菜单项必须始终处于活动状态,加上 (1 OR 2 OR 3 )。例如,仪表板被接受为共享 slug。否则会有一些排名检查。

现在我一直在努力使用 eloquent en query builder =/ 我认为没有必要设置关系,因为我只将它用于菜单和中间件。在这种情况下,仅包含 admin_item_id 和 user_id 的 f_user_access 表并没有真正用作数据透视表,也不会在其他任何地方使用。

    $items =
    $this->where( 'active', 1 )
         ->where( function ($query) {

              $query->whereIn( 'slug', $this->shared_slugs )
                    ->orWhere(function ($query) {

                        $query->whereRaw( $this->threshold_rank.' <= '.$this->user_rank )
                              ->whereIn('id', function ($query) {

                                  $query->select('admin_item_id')->from('f_user_access')->where('user_id', $this->user_id)->get();
                              });
                     })
                     ->orWhere(function ($query) {

                        $query->whereRaw( $this->threshold_rank.' > '.$this->user_rank )
                              ->where( 'rank', '>=', $this->user_rank );
                     });
         })->orderBy( 'order', 'ASC' )->get();
Run Code Online (Sandbox Code Playgroud)

我喜欢第二个的原因是我可以将 $shared_slugs 作为数组传递,我不必先将其转换为字符串。但除此之外,我真的很讨厌它的外观,where(function($query){}) 等等……最重要的是,传递给这个函数的 $ids 在 where.functions 中是不可访问的,所以我必须首先在类中定义它们。

我喜欢第一个是因为命名绑定,它读起来并没有那么糟糕:S,而且 vars 也是可访问的。

不使用 eloquent 和 querybuilder 真的有那么糟糕吗?至少在某些情况下……你们会怎么做才能使第二个例子更好?=/

更新::

由于答案和反馈,我放弃了原始 sql。当前函数有5个作用域,为user_access做了一个(小)模型。

    $items =
    $this->active() //Only active items AND... 1, 2 or 3

        ->where( function ($query) {

            $query->shared_slug()             //  1

            ->orWhere(function ($query) {      // OR  2
                $query->access_required()
                ->whereIn('id', UserAccess::get_access( $this->user_id ) );
            })

            ->orWhere(function ($query) {      // OR  3
                $query->no_access_required()
                ->whereRaw( 'rank >= '.$this->user_rank );
            });

        })->ASC()->get(); 
Run Code Online (Sandbox Code Playgroud)

小智 5

使用查询构建器的主要好处是它使您远离了您选择的存储所使用的语言,即 MySQL、Oracle、SQLite 等。如果您切换数据库类型,您可能会被大量重构原始 SQL 所困扰. 相信我,当您开始一个项目并了解到情况就是如此时,这并不漂亮。

然而,总是有一些警告,这正是 Eloquent 也能够处理原始语句的原因。