所以我加载所有预算:
$budgets = auth()->user()->budgets()->get(); // With some eager loading and ordering, not needed for this example.
问题在于我在视图中执行某些检查的方式。以此片段为例:
@foreach($budgets as $budget)
if($budget->getRemainingAmount() < 1) // getRemainingAmount() performs 6 queries
class="danger"
@endif
@endforeach
现在我对上述方法有一个主要问题。我不介意6个查询,这就是它在幕后工作的方式,完全没问题。问题是,每次我在视图中调用方法时,都会再次运行6个查询,这意味着它们会一遍又一遍地重复。
我想要做的是,例如,在我的查询中包含该方法,并将其分配给变量。
$budgets = auth()->user()->budgets()->doSomethingToAssignThatMethodToSomeVariable()->get();
现在让我们说这个方法做了以下简单的事情:
public function getRemainingAmount()
{
return 100;
}
现在,在执行查询时,如何将方法getRemainingAmount()
分配给名为$remaining
的变量?或者,有没有更好的方法来解决这个问题呢?在我看来,我只想改变这个:
if($budget->getRemainingAmount() < 1)
对此(例如):
if($remaining < 1)
因此,每次调用方法时,我都可以多次执行检查,而不必一遍又一遍地运行6个查询。
有关如何以简单方式实现这一目标的任何想法?我实际上有多种方法导致相同的问题(现在我的调试栏说:66 statements were executed, 41 of which were duplicated, 25 unique
)。显然我想删除重复。
答案 0 :(得分:1)
您可能会对使用缓存存储重复查询结果感兴趣。
您甚至可以将Closure作为默认值传递。结果 如果指定的项目不存在,将返回Closure 缓存。传递Closure允许您推迟检索默认值 来自数据库或其他外部服务的值:
$value = Cache::get('key', function () {
return DB::table(...)->get();
});
您可以控制缓存结果的时间长度,并且可以显着提高性能并减少数据库负载。
为此,访问some-budget-result
$result = Cache::get('some-budget-result', function () {
return auth()->user()->budgets()->doSomethingToAssignThatMethodToSomeVariable()->get();
});
会运行一次查询,并且每次访问该缓存项时,都会得到相同的结果,没有其他查询。
https://laravel.com/docs/5.5/cache#retrieving-items-from-the-cache