如何使用EloquentWhere()优化Laravel中的数据库查询

来自菜鸟教程
跳转至:导航、​搜索

在本系列的前一部分中,您更新了演示应用程序以将链接组织到数据库中的列表中。 主应用程序视图现在显示一个菜单,其中包含当前在数据库中注册的所有列表,但该菜单还没有活动链接。

在本节中,您将在应用程序中创建一个新路由,以通过列表 显示链接 。 您还将学习如何在 Eloquent 中使用 where() 方法来更好地过滤数据库查询中的结果。

首先,在代码编辑器中打开 routes/web.php 文件:

routes/web.php

该文件目前具有以下内容:

路线/web.php

<?php
 
use Illuminate\Support\Facades\Route;
use App\Models\Link;
use App\Models\LinkList;
 
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
 
Route::get('/', function () {
    $links = Link::all()->sortDesc();
    return view('index', [
        'links' => $links,
        'lists' => LinkList::all()
    ]);
});
 

Route::get 调用为应用程序入口页面定义了一个 HTTP GET 路由。 当应用程序向 / 发出请求时,将触发该回调函数返回索引视图。

您现在将创建第二条路由来显示基于列表 slug 的链接列表。 slug 是一个短字符串,通常用于构建用户友好的 URL。 新路由必须查询数据库的 link_lists 表以获取将提供的 URL 参数作为其 slug 字段的列表。 如果无法找到包含该 slug 的列表,应用程序应通知用户 HTTP 404 或 not found 错误。

以下代码使用名为 link-list 的动态参数(由 {slug} 定义)创建 GET 路由。 这会:

  • 使用 LinkList Eloquent 模型通过 where() 方法查询数据库,使用 slug 作为搜索条件。 first() 方法将确保只返回一个对象。
  • 如果找不到具有指定 slug 的列表,则使用 abort 方法会引发 404 错误。
  • 如果找到有效列表,则呈现索引视图,并将列表作为模板参数提供。

$lists 参数用于构建列表菜单,$links 参数用于与当前版本的索引视图兼容,因为它循环使用该名称的变量。

routes/web.php 文件的底部包含以下代码:

路线/web.php

Route::get('/{slug}', function ($slug) {
    $list = LinkList::where('slug', $slug)->first();
    if (!$list) {
        abort(404);
    }
 
    return view('index', [
        'list' => $list,
        'links' => $list->links,
        'lists' => LinkList::all()
    ]);
})->name('link-list');
 

完成后保存文件。

虽然有 shortcuts 来实现引用 Eloquent 模型的路由,但在本教程中,我们重点使用 where() 方法进行学习。


要测试您的新路由是否按预期工作,您可以转到浏览器并访问默认列表页面的链接。 如果到目前为止您已完成本系列中的所有步骤并且您的数据库不为空,则默认列表页面应在以下本地地址可用:

http://localhost:8000/default

您将看到与以前相同的页面,但链接现在仅限于 default 列表中的链接。 如果您有其他列表,您可以通过将 URL 中突出显示的 default slug 替换为列表的 slug 来访问他们的页面。

配置好新路由后,您现在可以使用 route Blade 方法从模板视图动态生成链接列表的 URL。 您还可以自定义页眉以显示有关列表的信息,以防万一。

在代码编辑器中打开 resources/views/index.blade.php 文件:

resources/views/index.blade.php

该文件有 2 行需要更新。 首先,找到包含您在本系列的另一部分中创建的菜单的 subtitle 段落。 这是它现在的样子:

资源/视图/index.blade.php

        <p class="subtitle">
            @foreach ($lists as $list)<a href="#" title="{{ $list->title }}" class="tag is-info is-light">{{ $list->title }}</a> @endforeach
        </p>

您将使用 route 刀片方法更新 href 超链接以包含列表页面的当前 URL。 此方法需要将路由名称作为第一个参数,并将 URL 参数作为附加参数提供给方法调用。 将 # 字符替换为以下突出显示的内容:

资源/视图/index.blade.php

        <p class="subtitle">
            @foreach ($lists as $list)<a href="{{ route('link-list', $list->slug) }}" title="{{ $list->title }}" class="tag is-info is-light">{{ $list->title }}</a> @endforeach
        </p>

接下来,找到 links 部分和其中的 foreach 循环。 您需要包含对 route() 方法的另一个调用,其中为每个链接打印列表名称。 这将类似于前面的示例,但是通过 $link 变量访问列表对象的方式不同:

资源/视图/index.blade.php

            <p>{{$link->url}}</p>
            <p class="mt-2"><a href="{{ route('link-list', $link->link_list->slug) }}" title="{{ $link->link_list->title }}" class="tag is-info">{{ $link->link_list->title }}</a></p>

接下来,当提供附加信息时,您可能希望包含有关列表的信息。 您可以检查 $list 变量是否存在,并仅在该变量可用时打印列表标题。

用以下突出显示的代码替换您的 title 部分:

        <h1 class="title">
            @if (isset($list))
                {{ $list->title }}
            @else
                Check out my awesome links
            @endif
        </h1>

这就是完成后 index.blade.php 文件的外观。 为方便起见,突出显示了这些更改:

资源/视图/index.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My Awesome Links</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.1/css/bulma.min.css">
 
    <style>
        html {
            background: url("https://i.imgur.com/BWIdYTM.jpeg") no-repeat center center fixed;
            -webkit-background-size: cover;
            -moz-background-size: cover;
            -o-background-size: cover;
            background-size: cover;
        }
 
        div.link h3 {
            font-size: large;
        }
 
        div.link p {
            font-size: small;
            color: #718096;
        }
    </style>
</head>
<body>
<section class="section">
    <div class="container">
        <h1 class="title">
            @if (isset($list))
                {{ $list->title }}
            @else
                Check out my awesome links
            @endif
        </h1>
        <p class="subtitle">
            @foreach ($lists as $list)<a href="{{ route('link-list', $list->slug) }}" title="{{ $list->title }}" class="tag is-info is-light">{{ $list->title }}</a> @endforeach
        </p>
 
        <section class="links">
            @foreach ($links as $link)
                <div class="box link">
                    <h3><a href="{{ $link->url }}" target="_blank" title="Visit Link: {{ $link->url }}">{{ $link->description }}</a></h3>
                    <p>{{$link->url}}</p>
                    <p class="mt-2"><a href="{{ route('link-list', $link->link_list->slug) }}" title="{{ $link->link_list->title }}" class="tag is-info">{{ $link->link_list->title }}</a></p>
                </div>
            @endforeach
        </section>
    </div>
</section>
</body>
</html>

完成更新其内容后保存文件。

您现在可以通过浏览器访问应用程序主页。 如果您使用包含的 Docker Compose 设置,则应用程序应该可以通过以下本地地址获得:

http://localhost:8000

您将获得类似于以下屏幕截图的页面:

在本系列的下一部分中,您将学习如何在 Laravel Eloquent 中对查询结果进行排序。