Model view controller 模型中的Symfony2实体管理器

Model view controller 模型中的Symfony2实体管理器,model-view-controller,symfony,doctrine,entitymanager,Model View Controller,Symfony,Doctrine,Entitymanager,我将在我的模型中使用实体管理器。但实体管理器仅在控制器中可用:throw$em=$this->get('doctrine.orm.entity\u manager')。因此,我必须使用$em参数定义模型方法。这使得phpUnit测试非常困难,并且违反了应用程序结构。例如: class Settings { public static function getParam( $em, $key ) { $em->createQuery("

我将在我的模型中使用实体管理器。但实体管理器仅在控制器中可用:
throw$em=$this->get('doctrine.orm.entity\u 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();
    }
}

在模型部分是否有使用实体管理器服务的方法?

在实体类中查询

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

实际上,我正在学习Doctrine2,并在思考类似的问题:将查询放在哪里

在条令1中有一些特殊的表类,我希望在条令2中也有类似的东西

存储库模式

今天我了解到条令2使用的是存储库模式:

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

不过,遵循存储库模式似乎是更好的选择

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

测试

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


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

首先,开始注意:按照惯例,您的实体类可能应该是单数的。所以,设置,而不是设置。你可以说“设置”作为一组相关设置可以被视为一个实体。不过,还是要记住一些事情

在Doctrine2中,您将使用存储库进行此类查询。在要调用
设置::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是专门设计的,不允许您在实体文件中使用查询;实体和实体管理器实际上是标准模型层的两个方面,它们分开以实施最佳实践。请参阅本文:

Hi,最后一个链接不见了。