如何在 Phalcon 中使用 QueryBuilder 和 Paginator 进行缓存?
How to Cache with QueryBuilder and Paginator in Phalcon?
我对 Phalcon 中的缓存有疑问。它与 Pagination 和 QueryBuilder 相关联。所以,我会给你举个例子:
$builder = $this->modelsManager->createBuilder()
->columns('a.*, m.*')
->addFrom('Models\Articles', 'a')
->leftJoin('Models\Multimedia', "m.parent_id=a.id AND m.is_default=1 AND m.subtype='pictures' AND m.type={m_type:str}", 'm')
->where('a.i18n={i18n:str} AND a.is_active_from IS NOT NULL AND a.is_active_from <= {today:str}', [
'i18n' => $this->session->i18n,
'm_type' => 'Models\Articles',
'today' => date("Y-m-d H:i:s")
])
->orderBy('a.is_accent DESC, a.date DESC, a.id DESC');
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder([
"builder" => $builder,
"limit" => 33,
"page" => $this->request->getQuery('page', 'int')
]);
$this->view->page = $paginator->getPaginate();
现在...如果我们跳过带有查询参数和子句的部分...那么...我的问题是:
这里如何添加缓存查询?
在 Phalcon 文档中,我只能使用 getQuery 函数添加 ->cache,但在我的例子中,这里没有这样的东西.
所以,问题仍然存在:在那种情况下我如何使用缓存?
谢谢
因为 getQuery() 调用 getPhql() internally 无论如何,我看到的最简单的解决方案就是调用
->getPhql()
在查询生成器上,然后从那里将字符串扔到 createQuery 中,如下所示:
$query = $this->modelsManager->createQuery($phql);
从那里调用 $query->cache(...)
,然后调用 execute()
作为 normal。
getPhql() 并不像他们在手册的 caching 部分中建议的用法那样看起来那么笨拙。
好吧...经过几周的思考 xD...我找到了一些适合我的问题的答案。
首先我们需要在 Phalcon 中有缓存服务:
$di->set('dataCache', function() use ($config) {
$lifetime = 60*60; // 1 hour
if ($config->development) {
$lifetime = 60; // 1 min
}
$frontCache = new \Phalcon\Cache\Frontend\Data([
"lifetime" => $lifetime
]);
$cache = new \Phalcon\Cache\Backend\File($frontCache, [
"cacheDir" => $config->application->cache_dir."data/"
]);
return $cache;
});
现在进入控制器,我的分页在哪里(你可以从第一个开始比较post):
$builder = $this->modelsManager->createBuilder()
->columns('a.id, a.slug, a.is_accent, a.type, a.title, m.*')
->addFrom('Models\Articles', 'a')
->leftJoin('Models\Multimedia', "m.parent_id=a.id AND m.is_default=1 AND m.subtype='pictures' AND m.type={m_type:str}", 'm')
->where('a.i18n={i18n:str} AND a.is_active_from IS NOT NULL AND a.is_active_from <= {today:str}', [
'i18n' => $this->session->i18n,
'm_type' => 'Models\Articles',
'today' => date("Y-m-d H:i:s")
])
->orderBy('a.is_accent DESC, a.date DESC, a.id DESC');
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder([
"builder" => $builder,
"limit" => 33,
"page" => $this->request->getQuery('page', 'int', 1)
]);
// Cache
$cache_key = 'articles-index-'.$this->request->getQuery('page', 'int', 1);
if ($this->di->has('dataCache') and $this->dataCache->exists($cache_key)) {
$this->view->page = $this->dataCache->get($cache_key);
} else {
$this->view->page = $paginator->getPaginate();
if ($this->di->has('dataCache')) {
$this->dataCache->save($cache_key, $this->view->page);
}
}
所以,重要的部分是 最后几行 在“// 缓存”注释之后 :) 我没有缓存查询,我缓存了所有分页器数据。为了优化,指定我们需要哪些列是个好主意(在我的情况下,我有一个包含大量文本的列内容,所以我不需要它)。还有一件事 - 当你 change/delete 一些元素时,不要忘记刷新 缓存(来自示例的模型)......像这样(在模型中):
public function afterDelete()
{
// Clear articles cache (but first check if we have that service)
if ($this->getDI()->has('dataCache')) {
$this->getDI()->get('dataCache')->flush();
}
}
就是这样。从 127 毫秒的请求,现在我得到了 40 毫秒甚至更少:)。祝大家好运:)
一些有用的链接:Phalcon Models Cache, Improving Performance in Phalcon, Phalcon File Cache
我对 Phalcon 中的缓存有疑问。它与 Pagination 和 QueryBuilder 相关联。所以,我会给你举个例子:
$builder = $this->modelsManager->createBuilder()
->columns('a.*, m.*')
->addFrom('Models\Articles', 'a')
->leftJoin('Models\Multimedia', "m.parent_id=a.id AND m.is_default=1 AND m.subtype='pictures' AND m.type={m_type:str}", 'm')
->where('a.i18n={i18n:str} AND a.is_active_from IS NOT NULL AND a.is_active_from <= {today:str}', [
'i18n' => $this->session->i18n,
'm_type' => 'Models\Articles',
'today' => date("Y-m-d H:i:s")
])
->orderBy('a.is_accent DESC, a.date DESC, a.id DESC');
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder([
"builder" => $builder,
"limit" => 33,
"page" => $this->request->getQuery('page', 'int')
]);
$this->view->page = $paginator->getPaginate();
现在...如果我们跳过带有查询参数和子句的部分...那么...我的问题是:
这里如何添加缓存查询?
在 Phalcon 文档中,我只能使用 getQuery 函数添加 ->cache,但在我的例子中,这里没有这样的东西.
所以,问题仍然存在:在那种情况下我如何使用缓存?
谢谢
因为 getQuery() 调用 getPhql() internally 无论如何,我看到的最简单的解决方案就是调用
->getPhql()
在查询生成器上,然后从那里将字符串扔到 createQuery 中,如下所示:
$query = $this->modelsManager->createQuery($phql);
从那里调用 $query->cache(...)
,然后调用 execute()
作为 normal。
getPhql() 并不像他们在手册的 caching 部分中建议的用法那样看起来那么笨拙。
好吧...经过几周的思考 xD...我找到了一些适合我的问题的答案。
首先我们需要在 Phalcon 中有缓存服务:
$di->set('dataCache', function() use ($config) {
$lifetime = 60*60; // 1 hour
if ($config->development) {
$lifetime = 60; // 1 min
}
$frontCache = new \Phalcon\Cache\Frontend\Data([
"lifetime" => $lifetime
]);
$cache = new \Phalcon\Cache\Backend\File($frontCache, [
"cacheDir" => $config->application->cache_dir."data/"
]);
return $cache;
});
现在进入控制器,我的分页在哪里(你可以从第一个开始比较post):
$builder = $this->modelsManager->createBuilder()
->columns('a.id, a.slug, a.is_accent, a.type, a.title, m.*')
->addFrom('Models\Articles', 'a')
->leftJoin('Models\Multimedia', "m.parent_id=a.id AND m.is_default=1 AND m.subtype='pictures' AND m.type={m_type:str}", 'm')
->where('a.i18n={i18n:str} AND a.is_active_from IS NOT NULL AND a.is_active_from <= {today:str}', [
'i18n' => $this->session->i18n,
'm_type' => 'Models\Articles',
'today' => date("Y-m-d H:i:s")
])
->orderBy('a.is_accent DESC, a.date DESC, a.id DESC');
$paginator = new \Phalcon\Paginator\Adapter\QueryBuilder([
"builder" => $builder,
"limit" => 33,
"page" => $this->request->getQuery('page', 'int', 1)
]);
// Cache
$cache_key = 'articles-index-'.$this->request->getQuery('page', 'int', 1);
if ($this->di->has('dataCache') and $this->dataCache->exists($cache_key)) {
$this->view->page = $this->dataCache->get($cache_key);
} else {
$this->view->page = $paginator->getPaginate();
if ($this->di->has('dataCache')) {
$this->dataCache->save($cache_key, $this->view->page);
}
}
所以,重要的部分是 最后几行 在“// 缓存”注释之后 :) 我没有缓存查询,我缓存了所有分页器数据。为了优化,指定我们需要哪些列是个好主意(在我的情况下,我有一个包含大量文本的列内容,所以我不需要它)。还有一件事 - 当你 change/delete 一些元素时,不要忘记刷新 缓存(来自示例的模型)......像这样(在模型中):
public function afterDelete()
{
// Clear articles cache (but first check if we have that service)
if ($this->getDI()->has('dataCache')) {
$this->getDI()->get('dataCache')->flush();
}
}
就是这样。从 127 毫秒的请求,现在我得到了 40 毫秒甚至更少:)。祝大家好运:)
一些有用的链接:Phalcon Models Cache, Improving Performance in Phalcon, Phalcon File Cache