• Laravel 6.0 中更加强劲的子查询


    Laravel 6.0 中更加强劲的子查询
     

    如果你一直关注我的工作,你就会知道我推崇将我们的 Laravel 应用里面的工作更多地放到数据库层。 通过在数据库层完成更多工作,我们通常可以减少我们制造的数据库查询的数量,减少应用程序使用的内存量,并减少 Eloquent 处理模型所需的时间。 这可以带来一些非常显着的性能提升。

    将更多工作推到数据库层的一种很好的方法是使用子查询。 子查询允许您在另一个数据库查询中运行嵌套查询。 当无法通过关系查询查到结果时,这是获取辅助模型数据的强大方法,而无需进行任何额外的数据库查询。 您还可以在 order by 语句, where 语句和其他数据库子句中使用子查询。

    在 Laracon US 2019 talk 期间,我参考了我正在使用的查询构造器,这让我们在 laravel 中使用子查询变得更加简单。我已经向 laravel 提交了三个 pr , 将这些添加到 laravel 的内核中.

    概述:

     

    “Select” 子查询

    Pull request #29567 select() 和 addSelect() 查询构建器方法支持子查询

    举个例子,假设我们有一个目的地表 destinations 和一个到目的地的航班表 flightsflights 表包含一个 arrival_at 字段,表示航班何时到达目的地。

    在 Laravel 6.0 中使用了新的子查询功能,比如要查询全部目的地 destinations,以及抵达各目的地最后一班飞机的信息 name ,我们可以用单条语句这样查询:

    return Destination::addSelect(['last_flight' => Flight::select('name')
        ->whereColumn('destination_id', 'destinations.id')
        ->orderBy('arrived_at', 'desc')
        ->limit(1)
    ])->get();

    注意这里是怎么使用 Eloquent 来生成的子查询。这样的语法更好,更具有直观表现力。同样的,你也可以使用 query builder:

    return Destination::addSelect(['last_flight' => function ($query) {
        $query->select('name')
            ->from('flights')
            ->whereColumn('destination_id', 'destinations.id')
            ->orderBy('arrived_at', 'desc')
            ->limit(1);
    }])->get();
     

    “Order by” 子查询

    此外,Pull request #29563 使我们可以在查询生成器的  orderBy() 方法中使用子查询。继续我们上面的示例,我们可以根据最后一班航班到达目的地的时间对目的地进行排序。

    return Destination::orderByDesc(
        Flight::select('arrived_at')
            ->whereColumn('destination_id', 'destinations.id')
            ->orderBy('arrived_at', 'desc')
            ->limit(1)
    )->get();

    与选择一样,您也可以直接使用查询构建器来创建子查询。 例如,您可能希望根据用户的上次登录日期订购:

    return User::orderBy(function ($query) {
        $query->select('created_at')
            ->from('logins')
            ->whereColumn('user_id', 'users.id')
            ->latest()
            ->limit(1);
    })->get();
     

    “From” 子查询

    最后,Pull request #29602 使我们在查询构造器中的  from() 使用子查询成为可能。这些有时称为派生表。

    例如,你可能想要计算应用程序中用户的平均捐赠总额。 但是,在 SQL 中,嵌套聚合函数是不可能的:

    AVG(SUM(amount))

    相反,我们可以使用 from 子查询来计算它:

    return DB::table(function ($query) {
        $query->selectRaw('sum(amount) as total')
            ->from('donations')
            ->groupBy('user_id');
    }, 'donations')->avg('total');

    你可能不需要每天都用到这个,但是当你确实需要它的时候,它是必不可少的。

    如果您在 Laravel 之外使用 Eloquent,那么需要注意的一个突破性变化,在 Illuminate/Database/Capsule/Manager 对象上 table() 方法有明显的改变。它已从表 table($table, $connection = null) 更改为表 table($table, $as = null, $connection = null)

     

    了解更多

    如果您有兴趣了解更多关于子查询和其他高级数据库技术的信息,请务必关注我的博客,并观看我的 Laracon US 2019 talk 演讲。

    在 Laracon,我还发布了一个新的视频课程,我正在研究 Eloquent 的性能模式。本课程的目的是教 Laravel 开发人员如何把更多的工作推送到数据库层来大幅提高 Laravel 应用程序的性能,同时仍然使用 Eloquent ORM。如果你感兴趣的话,一定要加入邮件列表!

    本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
    我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

    原文地址:https://laravel-news.com/eloquent-subque...

    译文地址:https://learnku.com/laravel/t/33324

  • 相关阅读:
    LeetCode Arithmetic Slices
    LeetCode Number of Longest Increasing Subsequence
    LeetCode Longest Increasing Subsequence
    shrio注解的方式进行权限控制
    30分钟学会如何使用Shiro(转自:http://www.cnblogs.com/learnhow/p/5694876.html)
    eclipse逆向生成实体类
    redis2.3.7安装时出现undefined reference to `clock_gettime'
    使用Nginx+Lua(OpenResty)开发高性能Web应用
    shrio初体验(2)Realm
    shrio初体验(1)
  • 原文地址:https://www.cnblogs.com/mouseleo/p/12266484.html
Copyright © 2020-2023  润新知