4

我目前正在实施学说结果缓存,所以我已经设置

result_cache_driver: apc

进入我的配置。

然后我已经正确地在存储库中使用了查询缓存,例如

->setResultCacheId(sprintf('posts_for_user_%d', $userId))

当我在教义中使用这些东西时,第一个问题出现了:

$repository->findOneBy(array)
$repository->findBy(array)

这可能很容易在存储库中被覆盖。

我无法解决的问题是使用 ParamConverter 来使用学说缓存以及实体关联。

例如,如果我有一个与 Player 具有 OneToMany 关系的 Team 实体,我通常会这样做

$team->getPlayers()

我无法控制该查询的缓存。这在某种程度上可能吗?

4

1 回答 1

2

当您运行 find/findBy 之类的方法或通过 PersistentCollection 执行 $team->getPlayers() 处理时,UoW 使用 EntityPersister 和 ObjectHydrator 加载数据以水合对象。这些对象不支持结果缓存驱动程序。

另一方面,当您使用 DQL 或 QueryBuilder 时,您的代码会生成扩展 AbstractQuery 的 Query 对象。如果您查看 AbstractQuery::execute 内部,您将看到这段漂亮的代码,它使使用结果缓存驱动程序成为可能

$cache             = $queryCacheProfile->getResultCacheDriver();
$result            = $cache->fetch($cacheKey);

if (isset($result[$realCacheKey])) {
    return $result[$realCacheKey];
}

所以我的建议 - 尝试使用 QueryBuilder 和 leftJoins 在子集合上加载您的实体。

$this->createQueryBuilder('x')->select('x, p')->leftJoin('x.players', 'p')->....;

它将创造使用结果缓存驱动程序的可能性。

于 2012-11-19T19:42:02.860 回答