前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >laravel框架操作sql时使用Scope作用域

laravel框架操作sql时使用Scope作用域

作者头像
友儿
发布2022-09-11 14:45:35
发布2022-09-11 14:45:35
83200
代码可运行
举报
文章被收录于专栏:友儿友儿
运行总次数:0
代码可运行

应用场景

  • 某些SQL语句需要加某些共同的条件,例如status > 0,如果我们每条SQL语句都加的话显然是很麻烦的,作为一个优雅的框架,当然有相应的解决办法

编写作用域

Laravel 应用默认并没有为作用域预定义文件夹,所以你可以按照自己的喜好在 app 目录下创建 Scopes目录并实现接口(Illuminate\Database\Eloquent\Scope)的方法apply

代码语言:javascript
代码运行次数:0
复制
  <?php
  
  namespace App\Scopes;
  
  use Illuminate\Database\Eloquent\Scope;
  use Illuminate\Database\Eloquent\Builder;
  use Illuminate\Database\Eloquent\Model;
  
  
  class StatusScope implements Scope
  {
  
      /**
       * Apply the scope to a given Eloquent query builder.
       *
       * @param \Illuminate\Database\Eloquent\Builder $builder
       * @param \Illuminate\Database\Eloquent\Model $model
       * @return
       */
      public function apply(Builder $builder, Model $model)
      {
            return $builder->where('status', '>', 0);
      }
  }

使用作用域

只需要在你需要使用的模型的"boot启动"方法中使用static::addGlobalScope(new 你的作用域类);

代码语言:javascript
代码运行次数:0
复制
 <?php
             
     namespace App\Models;
             
     use App\Scopes\StatusScope;
     use Illuminate\Database\Eloquent\Model;
             
     class ScopeTest extends Model
     {
          protected static function boot()
          {
               parent::boot();
               static::addGlobalScope(new StatusScope());
             
          }
     }             

添加作用域后,如果使用 ScopeTest::all() 查询则会生成如下 SQL 语句:status>0 就是应用的效果

代码语言:javascript
代码运行次数:0
复制
   select * from `users` where `status` > 0

当然,假如你感觉到上面的方法比较麻,也可以使用匿名的全局作用域

代码语言:javascript
代码运行次数:0
复制
  <?php
  namespace App\Models;
  
  use Illuminate\Database\Eloquent\Builder;
  use Illuminate\Database\Eloquent\Model;
  
  class ScopeTest extends Model
  {
      protected static function boot()
      {
          parent::boot();
          static::addGlobalScope('status', function (Builder $builder){
              $builder->where('status','>', 1);
          });
      }
  }

有些查询并不想使用作用域,可以通过调用以下方法移除作用域

代码语言:javascript
代码运行次数:0
复制
ScopeTest::withoutGlobalScope(StatusScope::class)->get();                         //移除指定作用域
ScopeTest::withoutGlobalScope('status')->get();                                   //移除闭包定义的作用域
ScopeTest::withoutGlobalScopes()->get();                                          //移除所有作用域
ScopeTest::withoutGlobalScopes([oneScope::class, twoScope::class])->get();   //移除某些作用域   

Eloquent模型方法前加上一个 scope前缀来使用作用域

代码语言:javascript
代码运行次数:0
复制
   <?php
   
   namespace App\Models;
   use Illuminate\Database\Eloquent\Model;
   
   class ScopeTest extends Model
   {
       public function scopeStatus($query){
           return $query->where('status','>', 1);
       }
       public function scopeType($query){
           return $query->where('type','>', 0);
       }
   }

调用时不需要加scope前缀,类似于修改器/访问器,并且可以一次性调用多个方法。

代码语言:javascript
代码运行次数:0
复制
$users = ScopeTest::status()->type()->get();
ScopeTest::status()->orWhere(function (Builder $query) {
  $query->type();
})->get();
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应用场景
  • 编写作用域
  • 使用作用域
  • Eloquent模型方法前加上一个 scope前缀来使用作用域
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档