codecamp

预载入

预载入是用来减少 N + 1 查询问题。例如,一个 Book 模型数据会关联到一个 Author 。关联会像下面这样定义:

class Book extends Model {
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

现在考虑下面的代码:

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

上面的循环会执行一次查询取回所有数据库表上的书籍,然而每本书籍都会执行一次查询取得作者。所以若我们有 25 本书,就会进行 26次查询。

很幸运地,我们可以使用预载入大量减少查询次数。使用 with 方法指定想要预载入的关联对象:

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

现在,上面的循环总共只会执行两次查询:

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

使用预载入可以大大提高程序的性能。

当然,也可以同时载入多种关联:

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

甚至可以预载入巢状关联:

$books = Book::with('author.contacts')->get();

上面的例子中, author 关联会被预载入, author 的 contacts 关联也会被预载入。
预载入条件限制

有时您可能想要预载入关联,同时也想要指定载入时的查询限制。下面有一个例子:

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

}])->get();

上面的例子里,我们预载入了 user 的 posts 关联,并限制条件为 post 的 title 字段需包含 "first" 。

当然,预载入的闭合函数里不一定只能加上条件限制,也可以加上排序:

$users = User::with(['posts' => function($query)
{
    $query->orderBy('created_at', 'desc');

}])->get();

延迟预载入

也可以直接从模型的 collection 预载入关联对象。这对于需要根据情况决定是否载入关联对象时,或是跟缓存一起使用时很有用。

$books = Book::all();
$books->load('author', 'publisher');

你可以传入一个闭包来对查询构建器进行条件限制:

$books->load(['author' => function($query)
{
    $query->orderBy('published_date', 'asc');
}]);
关联查询
新增关联模型
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

环境配置

系统服务

哈希

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }