PHP Laravel是否缓存了DB函数结果



没有问题。我正在做一个涉及与一些遗留软件交互的项目,该数据库与常规的Laravel Relationships不兼容。

如果我在这样的构造函数中定义东西:

public function __construct(array $attributes = array())
{
parent::__construct($attributes);
$this->vatpercentage = $this->customer()->vatpercentage;
$this->vatcode = $this->customer()->vatcode;
$this->partrevision = $this->part()->revision;
$this->unitprice = $this->part()->unitprice;
}
public function part(){
return Part::findOrFail($this->partnum);
}
public function customer(){
$traderid = Order::where('id', $this->orderid)->value('traderid');
return Customer::where('id', $traderid)->where('tradertype', 'C')->first();
}

我需要在构造函数中多次引用customer((、part((和其他类似的函数。是每次引用$this->customer((等时都会查询DB,还是第一次引用时缓存了结果,然后用于接下来的所有其他时间?基本上,我是不是用这种方式进行了很多不必要的DB调用,而不是设置$this->customer=$this-->customer((并获取$this->customer->example之类的值?

应用程序中不会自动缓存数据库查询或方法调用,也不应该自动缓存。Laravel和PHP不知道如何使用查询或方法。

每次调用customer((,都是在构建并执行一个新的查询。如果你想要的话,你可以很容易地将结果缓存在一个属性中,但你必须注意$orderid属性的值:

protected $customerCache;
public function customer()
{
if ($customerCache) return $customerCache;
$traderid = Order::where('id', $this->orderid)->value('traderid');
return $customerCache = Customer::where('id', $traderid)->where('tradertype', 'C')->first();
}

您在构造函数中也执行了太多。我强烈建议不要在任何构造函数中执行查询,构造函数应该用于传递依赖关系。它的设计方式会使单元测试变得非常困难。

在Laravel 4.*中,有一个remember((方法处理查询中的缓存。它被从5.1中删除,原因是Eloquent不负责处理缓存,查询生成器也不负责。一个非常简化的decorator类版本,可以处理查询的缓存:

final class CacheableQueryDecorator
{
private $remember = 60; //time in minutes, switch to load from config or add a setter
private $query = null;
public function __construct(Builder $builder)
{
$this->query = $builder;
}
private function getCacheKey(string $prefix = ''):string
{
return md5($prefix . $this->query->toSql() . implode(',', $this->query->getBindings()));
}
public function __call($name, $arguments)
{
$cache = Cache::get($this->getCacheKey($name), null);
if ($cache) {
return $cache;
}
$res = call_user_func_array([$this->query, $name], $arguments);
Cache::put($this->getCacheKey($name), $res, $this->remember);
return $res;
}
}

使用它:

$results = (new CacheableQueryDecorator($query))->get()

最新更新