菜鸟问题。我正在一个项目中,该项目涉及与一些旧版软件进行交互,并且该数据库与常规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之类的值吗?
答案 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()