如何在Phalcon中使用QueryBuilder和Paginator进行缓存?

时间:2016-09-18 14:26:24

标签: caching pagination phalcon

我对Phalcon中的Cache有疑问。它与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 函数添加 - &gt;缓存,但在我的情况下 - 这里没有这样的东西。

所以,问题仍然存在:如何在这种情况下使用缓存?

由于

2 个答案:

答案 0 :(得分:1)

嗯......经过几个星期的思考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;
});

现在进入控制器,我的分页在哪里(你可以从第一篇文章比较):

     $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);
        }
    }

因此,重要的部分是&#34; // Cache&#34;之后的最后几行。评论:)我没有缓存查询,我缓存所有的paginator数据。为了优化,最好指定我们需要哪些列(在我的情况下,我有一个包含大量文本的列内容,所以我不需要它)。还有一件事 - 当您更改/删除某个元素时,不要忘记刷新缓存(来自示例中的模型)...像这样(在模型中):

public function afterDelete()
{
    // Clear articles cache (but first check if we have that service)
    if ($this->getDI()->has('dataCache')) {
        $this->getDI()->get('dataCache')->flush();
    }
}

就是这样。从127ms请求,现在我有40ms甚至更少:)。祝你好运:)

一些有用的链接:Phalcon Models CacheImproving Performance in PhalconPhalcon File Cache

答案 1 :(得分:0)

因为getQuery()无论如何调用getPhql()internally,我看到的最简单的解决方案就是调用
查询构建器上的->getPhql(),然后从那里将字符串抛出到createQuery,如下所示:

$query = $this->modelsManager->createQuery($phql);

从那里拨打$query->cache(...),然后拨打execute()作为normal getPhql()并不像他们在本手册的caching部分中提出的那样使用它。“/ p>