4

我正在研究在我的 Zend Framework 设置中使用 Doctrine2。我真的很喜欢 datamapper 模式,主要是因为它将我的域模型与我的数据库分开。

我的问题是在我的控制器中使用 Doctrine 和 DQL 的最佳实践是什么?

  1. 控制器直接使用 Doctrine DQL/EntityManager 来保存/加载我的域模型?

  2. 在 datamapper 模式中创建我自己的类来保存/加载我的域模型,然后在我自己的类中内部使用 Doctrine?

专业人士。因为#1当然是我不需要创建自己的数据映射器模型,但同样,使用#2我可以稍后替换Doctrine(理论上)

你会怎么办?

4

5 回答 5

3

关于您的抽象问题,我想说这实际上取决于该项目的生命周期以及您的代码需要的可移植性。如果它是一个只需要最少维护的一次性网站,那么放弃额外的抽象层并在控制器中编写 Doctrine 代码可能会节省您一些时间。但是,如果您打算重用此代码、将其移至不同平台或长期维护它,我会花时间添加该抽象,因为它会给您更多的灵活性。

如果您仍在研究框架,请查看Kohana。它基本上是为 PHP5 编写的 CodeIgniter 的轻量级重写。

于 2009-09-24T16:47:16.660 回答
2

我赞同 pix0r 的建议。仅当它是一个具有潜在较长生命周期并且可能有许多开发人员参与的较大项目时,额外的抽象才值得。这几乎也是我遵循的指导方针,无论是在 php 中使用教义 2 还是在 java 中使用 jpa(因为教义 2 与 jpa 非常相似)。

如果你想要额外的抽象,doctrine2 已经提供了使用存储库的可能性(存储库非常相似甚至等同于 DAO,可能更侧重于业务术语和逻辑)。有一个基类 Doctrine\ORM\EntityRepository。每当您调用 EntityManager#getRepository($entityName) 时,Doctrine 都会查看您是否为该实体配置了自定义存储库类。如果没有,它会实例化一个 Doctrine\ORM\EntityRepository。您可以为元数据中的实体配置自定义存储库类,例如在 docblock 注释中:@Entity(..., repositoryClass="My\Project\Domain\UserRepository")。这样的自定义类应该从 EntityRepository 继承并适当地调用父构造函数。基类已经包含一些基本的 find* 功能。

罗马

于 2009-09-27T08:30:46.040 回答
1

在你的研究中也要考虑 Symfony。它会让你使用 ORM(propel/doctrine) 或者你可以编写自己的数据模型。如果需要,您还可以绕过数据关系并使用直接 SQL。

为了解决您对 1 或 2 的担忧,我个人在我的项目中使用 ORM 并在需要时绕过它。使用 symfony 更好的是,如果需要,您可以在教义和推进或您自己的类之间切换。

Pros:
1) faster development. easier to maintain. generally more secure and consistent. easy to switch databases should you ever need to.(from MySQL to Oracle, etc). 

2) Faster runtime. Less dependency.

Cons:
1) Slower runtime and larger memory footprint. Dependency on other projects.
2) (reverse the pros for #1) 
于 2009-09-24T16:35:55.420 回答
1

我的想法和 pix0r 的回复差不多。但是,如果您的项目足够小以至于您可以直接在控制器中使用 EntityManager/DQL,那么 Doctrine 2 可能对您的项目来说太过分了,也许您应该考虑一个更小/更简单的系统。

于 2010-11-01T00:26:49.383 回答
0

根据我在控制器中编写持久层逻辑的经验,总是以技术债务的形式困扰着我。现在这个看似很小的决定可能会在未来导致不可避免的和潜在的大规模重构,即使是在小型项目中也是如此。理想情况下,我们希望能够复制和粘贴使用适当模型重新配置的极薄控制器,以防止我们不得不一遍又一遍地重复创建 CRUD 控制器,但也允许自定义这些控制器。在我看来,这只能通过遵守纪律并尽可能将持久层从我们的应用程序中抽象出来来实现。由于这样做的开销特别是在洁净室控制器上是最小的,我看不出有什么好的理由建议你不要这样做。

于 2011-11-07T22:43:16.670 回答