【问题标题】:Where do we have to write queries in Laravel: in model, controller or routes?在 Laravel 中,我们必须在哪里编写查询:在模型、控制器或路由中?
【发布时间】:2016-03-30 16:49:42
【问题描述】:

我对 laravel 中的数据库查询有点困惑,我们必须在哪里编写查询:在控制器、模型或路由中?

我已经学习了很多教程,我看到了很多不同之处。只会制造混乱。

请解释一下

【问题讨论】:

    标签: php laravel laravel-5 orm eloquent


    【解决方案1】:

    这取决于不同的因素,但总之你可以在模型、控制器或存储库中编写它们

    如果你正在编写一个控制器动作并且你需要一个只使用一次的查询,那么直接在控制器中编写查询(甚至在路由的闭包中)是非常好的.

    例如,如果要获取admin 类型的所有用户:

    $admins = User::where('type', 'admin')->get();
    

    现在,假设您需要让管理员使用不止一种控制器方法;无需重写相同的查询,您可以创建一个 Repository 类来包装对用户模型的访问并在 Repository 中编写查询

    class UserRepository
    {
        public function getAllAdmins()
        {
            return User::where('type', 'admin')->get();
        }
    }
    

    现在在您的控制器中,您可以注入存储库并使用与存储库相同的方法来获取管理员用户:这将使您的代码保持干燥,因为您不必在控制器的操作中重复相同的查询

    控制器

    public function __construct(UserRepository $userRepo)
    {
         $this->userRepo = $userRepo;
    } 
    
    //controller action
    public function index()
    {
         $admins = $this->userRepo->getAllAdmins(); 
    }
    

    最后,假设您需要一个查询来计算管理员用户的数量。您可以在UserRepository 中编写此查询:

    public function getAdminNum()
    {
        return User::where('type', 'admin')->count();    
    }
    

    没关系,但我们可以注意到查询的User::where('type', 'admin') 片段与getAllAdmins 中的查询共享,因此我们可以通过使用query scopes 来改进这一点:

    用户模型

    public function scopeAdmins($query)
    {
        return $query->where('type', 'admin');    
    }
    

    由此,在UserRepository 方法中,我们可以将之前的查询重写为:

    public function getAllAdmins()
    {
        return User::admins()->get();
    } 
    
    public function getAdminNum()
    {
        return User::admins()->count();  
    }
    

    我刚刚向您展示了一个查询将被写入模型中的案例

    【讨论】:

    • 我可以在哪里存储我的存储库?我的意思是在一个特定的位置。
    • @JcJohn 你可以阅读这篇文章了解更多信息:medium.com/employbl/…
    【解决方案2】:

    您没有在Model 中编写任何查询。 Model 仅用于映射您要用于表的类,例如用户模型将映射到用户(模型名称的复数)。

    你不会像这样在路由闭包中编写查询

    Route::get('/', ['as' => 'home', function(){
        $totalProblems = Problem::count();
    
        $solvedProblems = Problem::where('solved', 1)->get()->count();
    
        $unsolvedProblems = Problem::where('solved', 0)->get()->count();
    
        return view('Pages.index', ['totalProblems' => $totalProblems, 'solvedProblems' => $solvedProblems, 'unsolvedProblems' => $unsolvedProblems]);
    }]);
    

    这被认为是不好的做法,仅用于测试目的。

    你总是像这样在与你的路由相关的控制器方法中编写你的查询

    Route::get('test', 'HomeController@test');
    

    在你的HomeController

    <?php namespace App\Http\Controllers;
    use App\Problem;
    
        class HomeController extends Controller {
    
            public function test(){
                $user = User::all();
                return view('Pages.test')->withUser($user); //or
    
                return view('Pages.test')->with('user' , $user);
            }
        }
    

    【讨论】:

    • 我不会说“总是”,有时您不会将查询直接放在控制器中,例如在存储库模式中
    • 是的,我同意,但我们会避免这种情况,因为路线并不是纯粹为此而设计的。 @amirbar
    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多