Php 原则2-如何在关系中使用从缓存检索的对象
我在一个项目中工作,在Symfony 2中使用了条令2,我使用MEMCACHE来存储条令的结果。 我对从MEMCACHE检索的对象有问题 我发现这篇文章很相似,但这种方法并不能解决我的问题: 情况就是这样Php 原则2-如何在关系中使用从缓存检索的对象,php,symfony,caching,doctrine-orm,doctrine,Php,Symfony,Caching,Doctrine Orm,Doctrine,我在一个项目中工作,在Symfony 2中使用了条令2,我使用MEMCACHE来存储条令的结果。 我对从MEMCACHE检索的对象有问题 我发现这篇文章很相似,但这种方法并不能解决我的问题: 情况就是这样 /** * This is in entity ContestRegistry * @var contest * * @ORM\ManyToOne(targetEntity="Contest", inversedBy="usersRegistered") * @ORM\JoinCo
/**
* This is in entity ContestRegistry
* @var contest
*
* @ORM\ManyToOne(targetEntity="Contest", inversedBy="usersRegistered")
* @ORM\JoinColumn(name="contest_id", referencedColumnName="id", onDelete="CASCADE"))
*
*/
protected $contest;
在其他实体中
/**
* @var usersRegistered
*
* @ORM\OneToMany(targetEntity="ContestRegistry", mappedBy="contest")
*
*/
protected $usersRegistered;
现在假设竞赛在缓存中,我想保存一个竞赛注册表项。
因此,我在缓存中检索对象竞赛,如下所示:
$contest = $cacheDriver->fetch($key);
$contest = $this->getEntityManager()->merge($contest);
return $contest;
就像我上次做的那样:
$contestRegistry = new ContestRegistry();
$contestRegistry->setContest($contest);
$this->entityManager->persist($contestRegistry);
$this->entityManager->flush();
我的问题是,条令正确地保存了新实体,但它也对实体竞赛进行了更新,并更新了更新的列。真正的问题是它对每个条目进行更新查询,我只想添加对实体的引用。
我怎样才能做到这一点?
任何帮助都将不胜感激。为什么
当实体合并回EntityManager时,它将被标记为脏。这意味着在执行刷新时,将在数据库中更新实体。这对我来说似乎是合理的,因为当您管理一个实体时,实际上需要EntityManager来管理它;)
在您的情况下,您只需要该实体与另一个实体进行关联,因此实际上不需要对其进行管理。因此,我建议采取不同的办法
使用参考资料
因此,不要将$contest
合并回EntityManager,而是获取对它的引用:
$contest = $cacheDriver->fetch($key);
$contestRef = $em->getReference('Contest', $contest->getId());
$contestRegistry = new ContestRegistry();
$contestRegistry->setContest($contestRef);
$em->persist($contestRegistry);
$em->flush();
该引用将是一个代理(除非它已经被管理),并且根本不会从数据库加载(甚至在刷新EntityManager时也不会)
结果缓存
除了使用您自己的缓存机制之外,您还可以使用Doctrine的缓存机制。它缓存查询结果以防止访问数据库,但(如果我没有弄错的话)仍然会缓存这些结果。这就避免了缓存实体本身可能出现的许多问题。您想要实现的是所谓的部分更新。 你应该用这样的东西来代替
/**
* Partially updates an entity
*
* @param Object $entity The entity to update
* @param Request $request
*/
protected function partialUpdate($entity, $request)
{
$parameters = $request->request->all();
$accessor = PropertyAccess::createPropertyAccessor();
foreach ($parameters as $key => $parameter) {
$accessor->setValue($entity, $key, $parameter);
}
}
合并要求整个实体100%充满数据。
我还没有检查孩子们的行为(多对一、一对一等)关系
部分更新通常用于Rest API上的补丁(或PUT)。您好,我尝试了两种解决方案,但第一种都不起作用。我不知道为什么。参考它的工作原理。也许当我更改跟踪策略时,我应该修改关系中涉及的所有实体?我已经研究过了,似乎不管更改跟踪策略如何,该实体都被标记为脏实体。所以这不是一个选择。我已经更新了我的答案。顺便说一句:我确实建议对所有实体使用延迟显式,因为刷新变得便宜得多。假设您加载了5000个实体并更改了1,延迟隐式将检查所有5000个,延迟显式将只检查您在上调用的1
$em->persist()
。