Symfony2 模型中的实体管理器

发布于 2024-10-16 21:06:06 字数 517 浏览 10 评论 0原文

我将在我的模型中使用entity_manager。但entity_manager仅在控制器中可用:throw $em = $this->get('doctrine.orm.entity_manager')。因此,我必须使用 $em 参数定义模型方法。这使得 phpUnit 测试变得非常困难并且违反了应用程序结构。例如:

class Settings
{
    public static function getParam( $em, $key )
    {
        $em->createQuery("
            SELECT s
            FROM FrontendBundle:Settings s
            WHERE s.param = {$key}
        ");
        return $em->getResult();
    }
}

有没有办法在模型部分使用entity_manager服务?

I'm going to use entity_manager in my model. But entity_manager is only available in controller: throw $em = $this->get('doctrine.orm.entity_manager'). So, I have to define model methods with $em parameter. This is making phpUnit testing pretty difficult and violates application structure. For example:

class Settings
{
    public static function getParam( $em, $key )
    {
        $em->createQuery("
            SELECT s
            FROM FrontendBundle:Settings s
            WHERE s.param = {$key}
        ");
        return $em->getResult();
    }
}

Is there any approach to use entity_manager service in model section?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青柠芒果 2024-10-23 21:06:06

首先,开始说明:按照惯例,您的实体类可能应该是单一的。所以,设置,而不是设置。您可能会争辩说,“设置”作为一组相关设置可以被视为一个实体。尽管如此,还是要记住一些事情。

在 Doctrine2 中,您将使用存储库来进行此类查询。在您要调用 Settings::getParam 的代码中,您将获取存储库并对其进行查询。在 symfony2 中,假设:

// $em is your entitymanager, as you were going to pass to your method above
// $key is the key you were going to pass to your method above
$repository = $em->getRepository('\FrontendBundle\Settings');
$setting = $repository->getByParam($key);

默认情况下,无需编写任何代码,存储库就会为实体中的每个字段定义 getByXXXX。

如果要进行更复杂的查询,可以扩展存储库。

use Doctrine\ORM\EntityRepository;

class SettingsRepository extends EntityRepository 
{
    public function getBySomeComplicatedQuery() {
        $sort_order = $this->getEntityManager()
            ->createQuery('SELECT count(s) FROM FrontendBundle\Settings s WHERE s.value > 32')
            ->getResult(Query::HYDRATE_SINGLE_SCALAR);
    }

}

然后你会以同样的方式调用该方法。

其他人会提倡使用 Manager 对象,这样它就不会与实体/ORM 绑定,但我认为在这种情况下这是不必要的复杂化。

Doctrine2 专门设计用于不允许您在实体文件中使用查询;实体和 EntityManager 实际上是标准模型层的两个方面,分开以实施最佳实践。请参阅这篇文章:http://symfony2basics.jkw.co.nz/get- symfony2-工作/实体/

First, a starting note: by convention your Entity class should probably be singular. So, Setting, not Settings. You could argue that "settings" as a group of related settings could be seen as one entity. Still, something to bear in mind.

In Doctrine2, you would use a repository to make this type of query. In your code where you were going to call Settings::getParam, you would instead fetch the repository and query that. In symfony2, say:

// $em is your entitymanager, as you were going to pass to your method above
// $key is the key you were going to pass to your method above
$repository = $em->getRepository('\FrontendBundle\Settings');
$setting = $repository->getByParam($key);

By default, without writing any code, repositories define getByXXXX for each field in your entity.

If you have a more complicated query to make, you can extend the repository.

use Doctrine\ORM\EntityRepository;

class SettingsRepository extends EntityRepository 
{
    public function getBySomeComplicatedQuery() {
        $sort_order = $this->getEntityManager()
            ->createQuery('SELECT count(s) FROM FrontendBundle\Settings s WHERE s.value > 32')
            ->getResult(Query::HYDRATE_SINGLE_SCALAR);
    }

}

And then you'd call that method in the same way.

Others would advocate the use of a Manager object which would then not be tied to the Entity/ORM, but that's a needless complication in this case I think.

Doctrine2 is specifically designed to not let you use queries in your Entity file; Entities and EntityManagers are actually two aspects of the standard model layer, split apart to enforce best practices. See this article: http://symfony2basics.jkw.co.nz/get-symfony2-working/entities/

冷…雨湿花 2024-10-23 21:06:06

实体类中的查询

将查询放入实体中对我来说似乎很奇怪。与在原则 1 中将查询放入模型类中的方式相同,这不被认为是一个好的实践。实体类应该是轻量级的。

我实际上正在学习 Doctrine2 并且正在考虑类似的问题:在哪里放置查询?

在 Doctrine 1 中有特殊的 Table 类,我期待在 Doctrine 2 中有类似的东西。

存储库模式

今天我了解到 Doctrine 2 正在使用存储库模式: doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html#custom-repositories" rel="noreferrer">http://www.doctrine-project.org/docs/orm/ 2.0/en/reference/working-with-objects.html#custom-repositories

但是,要检索存储库类的实例,您需要使用实体管理器。不管怎样,你都需要它。

尽管如此,遵循存储库模式似乎是更好的选择。

在我看来,如果您坚持在实体类中使用查询方法,则必须将实体管理器传递给它。

测试

为什么需要通过实体管理器会导致测试变得困难?根据我的经验,显式依赖关系使测试变得更容易,因为您可以在测试中控制它们(例如模拟它们)。

另一方面,将实体管理器传递给每个方法也不是正确的选择。在这种情况下,我会将依赖项设为强制性并将其添加到构造函数中。

Queries in the Entity class

Putting queries in you entity seems odd to me. The same way as putting queries into your model class in Doctrine 1 it is not considered a good practice. Entity classes should be light.

I'm actually learning Doctrine2 and was thinking about similar problem: where to put queries?

In Doctrine 1 there are special Table classes and I was expecting something similar in Doctrine 2.

Repository Pattern

Today I learned that Doctrine 2 is using the Repository Pattern: http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html#custom-repositories

However, to retrieve an instance of repository class you need to use Entity Manager. One way or another you need it.

Still, following the repository pattern seems a better choice.

In my opinion If you insist on having query method in your Entity class you have to pass an Entity Manager to it.

Testing

Why the need of passing entity manager makes it hard to test? From my experience explicit dependencies make testing easier as you can control them in the test (and mock them for example).

On the other hand passing the entity manager to every method is not right choice either. In such case I'd make the dependency obligatory and add it to the contructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文