php – Doctrine 2和ORM:如何缓存某个实体的每个查询?
发布时间:2020-12-13 13:30:14 所属栏目:PHP教程 来源:网络整理
导读:我很多时候都在解决这个问题,并且发现,正式地说,我只能缓存一些自定义查询(在Query对象上使用resultResultCache(true)).但我需要将我的应用程序中的每个查询缓存到某个表中.那么在EntityManager上查找*方法呢?… 有人可以帮我找到一个优雅的解决方案吗? 目
我很多时候都在解决这个问题,并且发现,正式地说,我只能缓存一些自定义查询(在Query对象上使用resultResultCache(true)).但我需要将我的应用程序中的每个查询缓存到某个表中.那么在EntityManager上查找*方法呢?…
有人可以帮我找到一个优雅的解决方案吗?
目前尚不支持此功能,您最终应该在服务层或扩展存储库中处理它.
您正在寻找的是second level cache as in Hibernate,它基本上允许您插入一个键值存储,如redis,riak,mongodb等,以便在操作简单的获取操作时快速启动. 在https://github.com/doctrine/doctrine2/pull/580有一项正在进行中的拉动请求,可能会在Doctrine ORM 2.5中登陆,所以请查看那个. use DoctrineORMEntityRepository; use DoctrineORMEntityManager; use DoctrineCommonCacheCache; use DoctrineCommonCacheArrayCache; class MyBaseRepo extends EntityRepository { public function __construct(EntityManager $entityManager) { parent::__construct($entityManager); $cache = $em->getConfiguration()->getHydrationCache(); $this->cache = $cache ?: new ArrayCache(); } public function find($id) { if (!$object = $this->tryFetchFromCache($id)) { $object = parent::find($id); $this->cache->save($this->generateKey($id),$object); } return $object; } protected function tryFetchFromCache($id) { if (!$object = $this->cache->fetch($this->generateCacheKey($id))) { return null; } return $this->getEntityManager()->merge($object); } public function generateCacheKey($id) { /* ... */ } } 在引导应用程序时,您可以强制将其作为配置中ORM的基本存储库: $configuration = new DoctrineORMConfiguration(); $configuration->setDefaultRepositoryClassName('MyMyBaseRepo'); 当您的任何实体发生更新/保存时,这也会强制您清除缓存条目: use DoctrineCommonEventSubscriber; use DoctrineORMEventOnFlushEventArgs; use DoctrineORMEvents; class IssueUpdateSubscriber implements EventSubscriber { public function onFlush(OnFlushEventArgs $args) { $em = $args->getEntityManager(); $uow = $em->getUnitOfWork(); if (!$cache = $em->getConfiguration()->getHydrationCache()) { return; } $busted = array_merge( $uow->getScheduledEntityUpdates(),$uow->getScheduledEntityDeletions(),); foreach ($busted as $entityToClear) { $className = get_class($entityToClear); $metadata = $em->getClassMetadata($className); $repository = $em->getRepository($className); $id = $metadata->getIdentifierValues($entityToClear); $cache->delete($repository->generateCacheKey($id)); } } public function getSubscribedEvents() { return array(Events::onFlush); } } 请注意,此实现不会拦截对给定实体的数据库的所有访问.它不会拦截由代理引起的延迟加载初始化,而且它非常脆弱,所以请设置一些适当的集成测试来支持它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |