zoukankan      html  css  js  c++  java
  • Laravel学习

    在Laravel中出现了两处针对数据库的Builder,一时分不清楚。

    EloquentBuilder

    QueryBuilder

    首先,确认EloquentBuilder与QueryBuilder是否是有继承关系:

    1/ 打印两者之间的instanceof关系,发现并没有关系

    2/ 查看源码:

    EloquentBuilder的构造器方法中有一个注入参数QueryBuilder

    /**
     * The base query builder instance.
     *
     * @var IlluminateDatabaseQueryBuilder
     */
    protected $query;
     
    /**
     * Create a new Eloquent query builder instance.
     *
     * @param  IlluminateDatabaseQueryBuilder  $query
     * @return void
     */
    public function __construct(QueryBuilder $query)
    {
       $this->query = $query;
    }
    

      可见两者之间并没有继承的关系,而是EloquentBuilder采用了代理模式对QueryBuilder进行了操作

    /**
        * Dynamically handle calls into the query instance.
        *
        * @param  string  $method
        * @param  array  $parameters
        * @return mixed
        */
    public function __call($method, $parameters)
    {
        if ($method === 'macro') {
            $this->localMacros[$parameters[0]] = $parameters[1];
     
            return;
        }
     
        if (isset($this->localMacros[$method])) {
            array_unshift($parameters, $this);
     
            return $this->localMacros[$method](...$parameters);
        }
     
        if (isset(static::$macros[$method])) {
            if (static::$macros[$method] instanceof Closure) {
                return call_user_func_array(static::$macros[$method]->bindTo($this, static::class), $parameters);
            }
     
            return call_user_func_array(static::$macros[$method], $parameters);
        }
     
        if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
            return $this->callScope([$this->model, $scope], $parameters);
        }
     
        if (in_array($method, $this->passthru)) {
            return $this->toBase()->{$method}(...$parameters);
        }
     
        $this->forwardCallTo($this->query, $method, $parameters);
     
        return $this;
    }
    

     

    EloquentBuilder中的__call方法,在最后也将当前类所有未能定位的方法全部forward到QueryBuilder执行。

    其次,如何使用EloquentBuilder,又如何使用QueryBuilder呢?

    Laravel中既提供了实例的使用,也提供了快捷的Facade使用方法。如:

    IlluminateSupportFacadesDB::table('user'); // --> object(IlluminateDatabaseQueryBuilder)

    UserModel::query(); // --> object(IlluminateDatabaseEloquentBuilder)

    可以看出,使用了FacadesDB得到的是QueryBuilder,而在UserModel的query方法调用后得到的是EloquentBuilder。

    个人认为:

    1/ DB的方法固然方便,但是更多的将table的信息硬编码,导致后期维护工作量大;

    2/ EloquentBuidler代理了QueryBuilder的方法,因此使用上也与DB的使用差别不大。

    在日常的操作中,我们更多的是定义了Model操作类。在Mode类中明确指定了表的名称:

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table;
    

    所以,更建议采用Model的方式进行操作。


    第三,EloquentBuilder与QueryBuilder得到的结果是否一致呢?

    /**
     * Use EloquentBuilder
     *
     */
    $eloquentBuilderResult = User::query()->where('name', 'test')->first();
    // var_dump($eloquentBuilderResult);
    // object(AppModelsUser) {}
     
    /**
     * Use QueryBuilder
     */
    $queryBuilderResult = DB::table('user')->where('name', 'test')->first();
    // var_dump($queryBuilderResult);
    // object(stdClass) {}
    

      

    因为定义的User对象是继承自IlluminateDatabaseEloquentModel(abstract),因此,所有的结果也均为User对象类型。在这一点上,与Yii2的ActiveRecord(User::find)对象非常相似。

    而QueryBuilder是直接对表数据进行操作,未与对象进行绑定映射关系等,所以在最后的结果呈现上,返回了stdClass的结果对象集。

      

     


    ————————————————
    版权声明:本文为CSDN博主「moonmovie」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/moonmovie/article/details/83817436

  • 相关阅读:
    python 网络爬虫框架scrapy使用说明
    计算机数据表示
    NoSQL 数据库应用
    什么是java序列化?什么情况下需要序列化?
    怎么实现动态代理?
    动态代理是什么?应用场景?
    什么是反射?有什么作用?
    nio中的Files类常用方法有哪些?
    什么是JAVA内部类?
    常见的异常类有哪些?
  • 原文地址:https://www.cnblogs.com/dreamboycx/p/15177355.html
Copyright © 2011-2022 走看看