使用原则 2 将实体保存到 REST API 而不是数据库
这与我的另一个问题有关:使用 REST API 持久化实体。
对于Symfony2中的项目,我需要能够使用远程(第三方)RESTful API来持久化实体。我还希望能够从该 API 中检索包含数据的实体。
换句话说,我的对象保存在第三方数据库中。它们不会保存在我自己的数据库中。每当我需要保存数据或查找数据时,我都会使用他们的 REST API。
有人指给我看好几个图书馆,包括一个由教义本身建立的图书馆。但是,它们都没有为我提供我想要的东西。Doctrine制作的那个是最好的选择,但使用Active Record模式,并没有提供所有甜蜜的Torism 2的东西。不要误会我的意思,我已经使用Active Record实现很长时间了,但我现在已经爱上了 Doctrine 的数据映射器模式。
理想情况下,我希望能够使用 Doctrine 的 ORM,并简单地将特定于数据库的部分替换为使用 API 调用保存实体的逻辑。(当然,使用相同的API检索它们)。通过这种方式,我可以使用大致相同的语法保存我的实体:
// current way to save $entity in database:
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
// desired way to save $entity using REST API:
// (just an example, it doesn't have to be exactly like this)
$em = $this->getDoctrine()->getManager('rest');
$em->persist($entity);
$em->flush();
请注意,我不是在尝试构建自己的API,我只是尝试与第三方API进行通信以保存我的实体。我对教义比较陌生,但到目前为止,我很喜欢它。我真的很喜欢将持久性逻辑与实体分离的想法,但到目前为止,我无法找到如何使用它来使用API保存它们。
Symfony的文档中有一篇文章描述了如何使用多个实体管理器。我正在寻找一个类似的解决方案,但是使用实体管理器,使我能够使用REST而不是DB。
我一直试图自己调整 Doctrine 的 ORM,但我最终只重写了一半的代码,因为它(似乎)与特定于数据库的逻辑过于紧密耦合。当然,我可能正在做一些愚蠢的事情。
所以我的问题是,有没有办法用自定义部分替换/覆盖学说ORM的数据库特定部分?不重写很多所有持久化方法都应该通用的东西?以前做过吗?还是根本不可能,因为学说旨在与数据库一起使用,并且对于其他用途不够灵活?
我自己的进步
CakePHP似乎能够通过让您定义自定义数据源来做到这一点。这样,您可以使用SQL数据库保存模型,也可以使用API,会话等保存模型。我想做大致相同的事情,但使用教义而不是CakePHP。
更新 1
实际的数据库查询似乎是由 Doctrine\ORM\Persisters\BasicEntityPersister
类执行的。还有其他几个xxxPersister类,用于处理不同类型的继承。也许可以用我们自己的类替换xxxPersister类,这样我们就可以用REST API代码替换DB代码。
持久化器对象是在 Doctrine\ORM\UnitOfWork
类的方法中创建的。类名是硬编码的,因此,如果我们要使用自己的持久化器,则需要重写。getEntityPersister()
Doctrine\ORM\UnitOfWork
更新 2
Doctrine\ORM\UnitOfWork
似乎被硬编码到 Doctrine\ORM\EntityManager
中,所以我们也需要覆盖它。但是,此类似乎包含一些特定于数据库的部分。例如,它的构造函数需要一个对象作为参数。也许最好创建我们自己的EntityManger(实现接口),只要这不会花费太多时间/精力。Doctrine\DBAL\Connection
Doctrine\Common\Persistence\ObjectManager
更新 3
用于检索/加载/查找对象的特定于数据库的代码与用于持久化/删除等的代码位于同一类中:类。因此,如果我们能够用我们自己的对象替换它们,为了持久化对象,我们也可以检索对象。例如,当您调用 时,它将返回(因为只是 的别名),它将运行以下代码:Doctrine\ORM\Persisters\xxxPersister
$entityRepository->findAll()
$entityRepository->findBy(array())
findAll()
findBy(array())
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->loadAll($criteria, $orderBy, $limit, $offset);
换句话说,一旦我们创建了权利和对象,我们将能够使用.EntityManager
UnitOfWork
xxxPersister
find
EntityRepository
更新 4
我发现为 Doctrine 开发了一个新功能:自定义持久化器(另请参阅此内容)。这应该使使用自定义持久化器类变得更加容易。我还不知道它是否能让我们创建一个非DB持久化器,但它看起来很有希望。但是,最后一次更新是在八月份,所以我不确定它是否仍在积极开发中。