【问题标题】:Inserting data with Doctrine - Repository Vs Entity使用 Doctrine 插入数据 - 存储库与实体
【发布时间】:2016-07-17 10:01:57
【问题描述】:

我已经意识到 Doctrine 存储库和 Doctrine 实体之间存在差异。

我正在尝试在表上实现简单的 CRUD 操作,并将默认 Doctrine 存储库注入我的控制器(不注入实体)。

对于“更新”操作,我首先要->find($id) 更新记录,它会返回一个实体实例,以便我绑定到我的表单对象。

对于“创建”操作,我意识到我不能->find($id) 插入一条记录(因为它不存在),以便检索实体的实例以绑定到我的表单对象。

是否有另一种方法可以在没有实体实例的情况下使用 Doctrine 插入数据?或者有没有办法从存储库中检索实体的实例,以便我可以->bind() 将其发送到表单?如果两者的答案都是否定的,那么我想我唯一的选择是将实体的实例注入我的控制器,或者使用自定义存储库,其中包含一个方法,该方法将返回一个实体以在->bind() 中使用以进行插入.

我的猜测是定义一个自定义存储库,该存储库有一个检索空实体实例以用于插入的方法。这个假设正确吗?

【问题讨论】:

  • 为什么需要在任何地方注入实例?这就是new 关键字的用途,它是一个新实体。在控制器中创建实体的新实例并绑定它。如果您不想在控制器中硬编码实体类名称,您可以使用存储库 getClassName() 方法获取实体类名称,然后创建一个新实例。
  • 如果我这样做了,那将是一个隐含的依赖关系,下一个处理此代码的人将很难弄清楚为什么在实体被删除、移动、重命名后类被破坏,等等。这样做很容易,然后就收工了,但是这种方法对于未来的开发来说是不可维护的。

标签: php orm doctrine-orm zend-framework2


【解决方案1】:

正如@Crisp 在 cmets 中指出的那样,实体只不过是 PHP 类,对于存储库也是如此。 两者的区别在于各自的角色。

您永远不会隐式创建存储库的新实例,因为教义会通过 DependencyInjection 原则(ServiceFactory、...)为您完成。

要创建新的数据库条目,您必须创建相应实体的新实例,然后使用EntityManager::persistEntityManager::flush 方法存储它。

重用实体的同一个实例不会给您带来任何好处,也不会对项目的可维护性产生任何影响。

实体类本身永远不会被破坏/更改,只会创建、重命名、移动、删除它们的实例。
这些实例代表您的数据库条目,这是使用 ORM 的主要兴趣。

【讨论】:

  • 我正在努力严格遵守这方面的最佳实践,也许我对“最佳实践”的理解是错误的。如果您需要特定类的实例才能使某些东西起作用,那么它就是依赖项。显式依赖是否优于隐式依赖。在请求的控制器内部使用 new 关键字不是因为它是隐式依赖关系而皱眉吗?为什么在这种情况下可以使用 new 关键字而不是其他关键字?
  • 我现在可以理解你的逻辑了。我认为这是因为实体应该被视为数据库条目的对象表示,而不是真正的依赖关系。我真的不知道为什么我们没有 EntityManager::getRepository([alias])->getNew() 例如,但结果将与 EntityManager::getRepository([entityAlias]) 相同(相应类的新实例)。
  • 即使在存储库中添加创建/更新/删除等方法,您也可以完美地保持代码遵循最佳实践。这是您自己的赞赏。
  • +1 @d.lanza38 这样想,如果您不使用 ORM,您只需传递数组表示数据。通过将$form->setObject(new Entity); 移动到表单工厂,您可以避免在控制器中对new Entity 进行硬编码。
  • 我意识到我可能需要在每次调用新方法时清空实体对象,以确保每次都是新鲜的。我会将其标记为答案,因为在答案和 cmets 之间,它就是答案。谢谢大家!
猜你喜欢
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 2012-07-08
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多