我需要进行查询并使用Doctrine实现的结果缓存。我按照http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#result-cache中指定的说明进行操作。
这是我的源代码:
<?php
namespace Fw\Entity;
use Doctrine\ORM\EntityRepository;
class VisitRepository extends EntityRepository {
public function getTotal() {
$memcached = new \Memcached();
$memcached->addServer('localhost', 11211);
$cacheDriver = new \Doctrine\Common\Cache\MemcachedCache();
$cacheDriver->setMemcached($memcached);
$datetime = new \Fw\Library\GMTDateTime('now');
$result = $this->createQueryBuilder('v')
->select('v.count as _count_today, v.countUnique as _count_unique_today, 0 as _count_total, 0 as _count_unique_total')
->where('v.date = :date')
->setParameter('date', $datetime, \Doctrine\DBAL\Types\Type::DATE)
->getQuery()
->setResultCacheDriver($cacheDriver)
->useResultCache(true, 3600, 'my_custom_id')
->execute();
var_dump($memcached->getAllKeys());
var_dump($memcached->get('my_custom_id'));
var_dump($cacheDriver->contains('my_custom_id'));
if (is_array($result)) {
$result = $result[0];
}
return $result;
}
}
当我加载页面时,运行SQL而不是使用缓存。
var_dumps显示:
array(1) { [0]=> string(17) "[my_custom_id][1]" }
bool(false)
bool(true)
似乎密钥是在memcached中创建的,但结果不是。
如果我使用 - &gt;设置手动设置memcached中的内容,稍后我使用 - &gt; get进行检索,那么这个效果非常好。
有人可以帮我解决这个问题吗?
感谢。
更新/更多信息:
如果我这样做
var_dump($cacheDriver->fetch('my_custom_id'));
我可以看到
array(1) {
["SELECT v0_.count AS count_0, v0_.countUnique AS countUnique_1, 0 AS sclr_2, 0 AS sclr_3 FROM visit v0_ WHERE v0_.date = ?-a:1:{i:0;O:22:"Fw\Library\GMTDateTime":3:{s:4:"date";s:26:"2016-08-29 17:59:36.000000";s:13:"timezone_type";i:2;s:8:"timezone";s:3:"GMT";}}-a:1:{i:0;s:4:"date";}"]=>
array(1) {
[0]=>
array(4) {
["count_0"]=>
string(2) "70"
["countUnique_1"]=>
string(1) "1"
["sclr_2"]=>
string(1) "0"
["sclr_3"]=>
string(1) "0"
}
}
}
如果我重新加载页面,我可以看到:
array(2) {
["SELECT v0_.count AS count_0, v0_.countUnique AS countUnique_1, 0 AS sclr_2, 0 AS sclr_3 FROM visit v0_ WHERE v0_.date = ?-a:1:{i:0;O:22:"Fw\Library\GMTDateTime":3:{s:4:"date";s:26:"2016-08-29 18:00:08.000000";s:13:"timezone_type";i:2;s:8:"timezone";s:3:"GMT";}}-a:1:{i:0;s:4:"date";}"]=>
array(1) {
[0]=>
array(4) {
["count_0"]=>
string(2) "72"
["countUnique_1"]=>
string(1) "1"
["sclr_2"]=>
string(1) "0"
["sclr_3"]=>
string(1) "0"
}
}
["SELECT v0_.count AS count_0, v0_.countUnique AS countUnique_1, 0 AS sclr_2, 0 AS sclr_3 FROM visit v0_ WHERE v0_.date = ?-a:1:{i:0;O:22:"Fw\Library\GMTDateTime":3:{s:4:"date";s:26:"2016-08-29 18:00:10.000000";s:13:"timezone_type";i:2;s:8:"timezone";s:3:"GMT";}}-a:1:{i:0;s:4:"date";}"]=>
array(1) {
[0]=>
array(4) {
["count_0"]=>
string(2) "73"
["countUnique_1"]=>
string(1) "1"
["sclr_2"]=>
string(1) "0"
["sclr_3"]=>
string(1) "0"
}
}
}
似乎每次重新缓存结果,而不是使用缓存(如果存在)。
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
我找到了问题的答案。
问题是由于我在中使用DateTime值引起的。生成密钥缓存时使用该值,因此每次生成新密钥时都会使用该值:
... me":3:{s:4:"date";s:26:"2016-08-29 18:00:08.000000";s:13:"ti ..
... me":3:{s:4:"date";s:26:"2016-08-29 18:00:10.000000";s:13:"ti ..
在我的情况下,我在数据库中的字段只是日期,所以我不需要DateTime的时间部分。
我用这种方式解决了我的缓存问题:
$datetime = new \Fw\Library\GMTDateTime('now');
$datetime->setTime(0, 0, 0); // NEW LINE !!!
$result = $this->createQueryBuilder('v')
->select('v.count as _count_today, v.countUnique as _count_unique_today, 0 as _count_total, 0 as _count_unique_total')
->where('v.date = :date')
->setParameter('date', $datetime, \Doctrine\DBAL\Types\Type::DATE)
->getQuery()
->setResultCacheDriver($cacheDriver)
->useResultCache(true, 3600, 'my_custom_id')
->execute();