作为程序员一定要保持良好的睡眠,才能好编程

laravel关联模型之预加载

发布时间:2020-01-31



预加载

https://learnku.com/docs/laravel/6.x/eloquent-relationships/5177#012e7e



预加载使用 with  load 都是可以实现预预加载方式的




也可以在模型中使用 $with 属性去设置。



当在模型中使用了with属性后,如果在使用中不想使用预加载,则可以使用 withOut 方法去设置。



案例:


<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
    /**
     * 获取书籍作者。
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}


现在,我们来获取所有的书籍及其作者:


$books = App\Book::all();
foreach ($books as $book) {
    echo $book->author->name;
}


此循环将执行一个查询,用于获取全部书籍,然后为每本书执行获取作者的查询。如果我们有 25 本书,

此循环将运行 26 个查询:1 个用于查询书籍,25 个附加查询用于查询每本书的作者。


谢天谢地,我们能够使用预加载将操作压缩到只有 2 个查询。在查询时,可以使用 with 方法指定想要预加载的关联:


预加载


$books = App\Book::with('author')->get();
foreach ($books as $book) {
    echo $book->author->name;
}


在这个例子中,仅执行了两个查询:


select * from books
select * from authors where id in (1, 2, 3, 4, 5, ...)


预加载多个关联

有时,你可能需要在单一操作中预加载几个不同的关联。要达成此目的,只要向 with 方法传递多个关联名称构成的数组参数:


$books = App\Book::with(['author', 'publisher'])->get();


延迟预加载

//举例来说,
//如果你想要根据某个动态条件决定是否加载关联数据,那么 load 方法对你来说会非常有用:

$books = App\Book::all();

if ($someCondition) {
    $books->load('author', 'publisher');
}

//如果你想要在渴求式加载的查询语句中进行条件约束,你可以通过数组的形式去加载,键为对应的关联关系,
//值为 Closure 闭包函数,该闭包的参数为一个 query 实例:

$books->load(['author' => function ($query) {
    $query->orderBy('published_date', 'asc');
}]);

//如果希望加载还没有加载的关联关系时,你可以使用 loadMissing 方法:

public function format(Book $book)
{
    $book->loadMissing('author');

    return [
        'name' => $book->name,
        'author' => $book->author->name,
    ];
}



默认预加载

有时可能希望在查询模型时始终加载某些关联。 为此,你可以在模型上定义 $with 属性:


例如:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * 默认加载的关联。
     *
     * @var array
     */
    protected $with = ['author'];

    /**
     * 获取书籍作者
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}


如果你想从单个查询的 $with 属性中删除一个预加载,你可以使用 without 方法:


$books = App\Book::without('author')->get();



为预加载添加约束

有时,可能希望预加载一个关联,同时为预加载查询添加额外查询条件,就像下面的例子:

$users = App\User::with(['posts' => function ($query) {
    $query->where('title', 'like', '%first%');
}])->get();



注意:在约束预加载时,不能使用 limit 和 take 查询构造器方法









Laravel预加载方式:

Laravel 预加载方式

image.png

以上的两种方式都是预加载的。


必须使用预加载,不要在view层 进行业务逻辑的判断。



还有一种方式就是 使用  $books->author  这不是预加载。



其他使用方式方法请参考:

预加载

https://learnku.com/docs/laravel/6.x/eloquent-relationships/5177#012e7e