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

时间:2018-12-18 13:25:27

标签: php database laravel

菜鸟问题。我正在一个项目中,该项目涉及与一些旧版软件进行交互,并且该数据库与常规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()等时查询数据库,还是在我第一次引用它时将结果缓存,然后在接下来的所有其他时间使用该结果?基本上,我是通过这种方式进行编码,而不是设置$ this-> customer = $ this-> customer()并获取诸如$ this-> customer-> example之类的值吗?

2 个答案:

答案 0 :(得分:1)

不会在应用程序中自动缓存数据库查询或方法调用,也不应该在应用程序中自动缓存该查询。 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();
}

您在构造函数中的性能也过高。我强烈建议不要在任何构造函数中执行查询,应该使用构造函数来传递依赖关系。您设计的方式将使其很难进行单元测试。

答案 1 :(得分:0)

在Laravel 4. *中,有一个Remember()方法处理查询中的缓存。从5.1中删除了它是有正当理由的,原因是这不是Eloquent的责任,也不是查询生成器来处理缓存。装饰器类的非常简化的版本,可以处理查询的缓存:

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()