Нуб вопрос. Я работаю над проектом, который предполагает взаимодействие с некоторыми устаревшими программами, а база данных несовместима с обычными отношениями Laravel.
Если я определяю вещи в конструкторе, как это:
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?
Ни запрос базы данных, ни вызов метода не будут автоматически кэшироваться в вашем приложении, и при этом это не должно происходить. 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 не отвечает ни за построитель запросов, ни за кеш. Очень очень упрощенная версия класса декоратора, которая может обрабатывать кэширование ваших запросов:
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()