资讯专栏INFORMATION COLUMN

laravel使用技巧之查询构造器Query Builder叠加链式调用

weapon / 1615人阅读

摘要:今天给大家介绍一下查询构造器的一个小技巧,在官方文档示例中没有详细提到,也不是啥高端技巧,可能很多人在用了,不知道的同学可以看看。改进后的写法如果用用变量保存查询构造器实例,然后在其上叠加约束条件,最后集合。

今天给大家介绍一下laravel查询构造器的一个小技巧,在官方文档示例中没有详细提到,也不是啥高端技巧,可能很多人在用了,不知道的同学可以看看。

在业务代码中经常会根据不同条件来查询,举个简单例子,我们现在要查询用户列表,按时间倒序排列,可能会有status和type作为限定条件。

一开始我是这样写的

    if($status && $type) {
        $users = User::where("status", $status)->where("type", $type)->latest()->get();
    } else if ($status) {
        $users = User::where("status", $status)->latest()->get();   
    } else if ($type) {
        $users = User::where("status", $type)->latest()->get();
    } else {
        $users = User::latest()->get();        
    }

这个代码真的很丑陋,很多公共代码,比如->latest()->get(),写了四遍,如果产品说今天我们要正序排列,那你得改四个地方。虽然借助编辑器改一下也很快,不过要知道这只是个最简单的例子。

看了下文档有个when方法进行条件判断,一堆闭包也不是很理想。我坚信肯定有更优雅的写法,于是上stackoverflow搜了一波,果然万能的歪果仁给了我答案。

改进后的写法:

    $query = User::query();
    // 如果用DB: $query = DB::table("user");
    
    if ($status) {
        $query->where("status", $status);
    }

    if ($type) {
        $query->where("type", $type);
    }
    
    $users = $query->latest()->get();

用变量保存查询构造器实例,然后在其上叠加约束条件,最后get集合。公共部分放在首尾,结构清晰,是不是高下立判啊?

而且我们还可以把$query当成参数传入方法或函数中,将公共逻辑封装在一起,方便多处调用:

    function foo($query) {
        $query->with(["girl", "gay"])
              ->latest()
              ->get();
    }
    
    
    $query = User::query();
    $users = foo($query);

这种写法有一个注意事项,一旦你在$query上调用where等约束方法,就会改变此query,有时候我们需要提前clone一个query。

举例说明,比如我们同时要拿到type为1和2的users

    $query_1 = User::query();
    $query_2 = clone $query_1;
   
   
    $users_1 = $query_1->where("type", 1)->latest()->get();
    $users_2 = $query_2->where("type", 2)->latest()->get();
    // 错误 $users_2 = $query_1->where("type", 1)->latest()->get();
    // 这样写得到得是type = 1 and $type = 2

laravel的文档里虽然没有写这种示例,但是提了一下:

你可以使用 DB facade 的 table 方法开始查询。这个 table 方法针对查询表返回一个查询构造器实例,允许你在查询时链式调用更多约束,并使用 get 方法获取最终结果

题外话

以前听一些老前辈说他们不要只会百度的程序员,当时感觉真装哔,不都是搜索引擎,因为我那时不用google。现在我也不愿意和只会百度的共事了,百度只是个广告搜索嘛,搜出来的都是些啥玩意。

google、stackoverflow真是个好东西,很多歪果仁知识丰富,解答专业,从计算机历史到操作系统、数据库、各种编程语言,帮我de了好多bug。在segmentfault这么打广告是不是不好,溜了!

Reference:
How to create multiple where clause query using Laravel Eloquent? - stackoverflow
Model::query - laravelAPI

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/26197.html

相关文章

  • Laravel 5.7 最佳实践和开发技巧分享

    摘要:当查询数据时,本地范围允许我们创建自己的查询构造器链式方法。这样便会知道这是一个本地范围并且可以在查询构造器中使用。某些查询构造器不可用或者说可用但是方法名不同,关于这些请查阅所有集合的方法。 showImg(https://segmentfault.com/img/remote/1460000017877956?w=800&h=267); Laravel 因可编写出干净,可用可调试的...

    ninefive 评论0 收藏0
  • Laravel 学习笔记 Query Builder 源码解析(中)

    说明:本篇主要学习数据库连接阶段和编译SQL语句部分相关源码。实际上,上篇已经聊到Query Builder通过连接工厂类ConnectionFactory构造出了MySqlConnection实例(假设驱动driver是mysql),在该MySqlConnection中主要有三件利器:IlluminateDatabaseMysqlConnector;IlluminateDatabaseQuery...

    zhou_you 评论0 收藏0
  • Laravel学习笔记Query Builder源码解析(上)

    摘要:说明本文主要学习模块的源码。这里,就已经得到了链接器实例了,该中还装着一个,下文在其使用时再聊下其具体连接逻辑。 说明:本文主要学习Laravel Database模块的Query Builder源码。实际上,Laravel通过Schema Builder来设计数据库,通过Query Builder来CURD数据库。Query Builder并不复杂或神秘,只是在PDO扩展的基础上又开...

    Steve_Wang_ 评论0 收藏0
  • Laravel Query Builder 复杂查询案例:子查询实现分区查询 partition b

    摘要:案例案例在文章列表中附带上前条评论,在获取文章列表时同时把每个文章的前条评论一同查询出来。这是典型分区查询案例,需要根据表中的字段进行分区,同时根据条件进行排序,把符合条件的前条是数据取出来。查询语句中定义变量以及函数的使用如何构建子查询。 案例 案例:Laravel 在文章列表中附带上前10条评论?,在获取文章列表时同时把每个文章的前10条评论一同查询出来。 这是典型分区查询案例,需...

    littleGrow 评论0 收藏0
  • Laravel核心解读--Database(四) 模型关联

    摘要:为关联关系设置约束子模型的等于父模型的上面设置的字段的值子类实现这个抽象方法通过上面代码看到创建实例时主要是做了一些配置相关的操作,设置了子模型父模型两个模型的关联字段和关联的约束。不过当查询父模型时,可以预加载关联数据。 Database 模型关联 上篇文章我们主要讲了Eloquent Model关于基础的CRUD方法的实现,Eloquent Model中除了基础的CRUD外还有一个...

    gekylin 评论0 收藏0

发表评论

0条评论

weapon

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<