Doctrine2存储库是保存实体的好地方吗?

时间:2011-12-03 18:35:48

标签: design-patterns symfony doctrine-orm soa service-layer

当我阅读有关存储库的文档时,通常会与实体和工作组合作。收集,但以“只读”的方式。

从来没有例子存储库包含insertUser(User $user)updateUser(User $user)等方法。

但是,在使用SOA时,Service不应该使用Entity Manager(这是对的,不是吗?)所以:

  1. 我的服务是否应该了解全局EntityManager?
  2. 我的服务是否应仅知道所使用的存储库(比方说,UserRepository& ArticleRepository)
  3. 从这两个问题,另一个问题,我的服务应该明确persist()& flush()我的实体?

3 个答案:

答案 0 :(得分:39)

是的,存储库通常仅用于查询。

我是这样做的。 service layer管理持久性。控制器层知道服务层,但不知道模型对象是如何持久存在的,也不知道它们来自何处。对于控制器层所关心的是要求服务层持久并返回对象 - 它并不关心它是如何实际完成的。

服务层本身非常适合了解持久层:实体或文档管理器,存储库等。

这里有一些代码可以让它更清晰:

class UserController
{
    public function indexAction()
    {
        $users = $this->get('user.service')->findAll();
        // ...
    }

    public function createAction()
    {
        // ...
        $user = new User();
        // fill the user object here
        $this->get('user.service')->create($user);
        // ...
    }
}

class UserService
{
    const ENTITY_NAME = 'UserBundle:User';

    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function findAll()
    {
        return $this->em->getRepository(self::ENTITY_NAME)->findAll();
    }

    public function create(User $user)
    {
        // possibly validation here

        $this->em->persist($user);
        $this->em->flush($user);
    }
}

答案 1 :(得分:3)

如果您查看存储库模式http://martinfowler.com/eaaCatalog/repository.html

据说存储库使用“类似集合的接口”。

稍后,它还写成“可以从存储库添加和删除对象,因为它们可以从简单的对象集合中添加”。

我不是说这是一本圣经,但从概念上讲,看到像你可以查询的集合这样的存储库并没有错。 但由于它是一个集合,你可以添加,删除,... 实际上,ObjectRepository应该实现Doctrine \ Common \ Collection:)

另一方面,最重要的是不要像读取CQS那样弄乱读写。 这也许就是为什么他们不直接允许这样做,以避免滥用和读/写混合。

编辑:我应该谈谈flush。这应该在存储库本身,因为它可能会破坏事务的一致性。

你最好将flush调用移动到包装整个业务事务逻辑的东西(处理命令f.e的命令总线)?

答案 2 :(得分:1)

那么,在不使用entityManager时如何获取存储库?毕竟,如果没有与数据库的连接,实体将不会神奇地保存,因此您的服务必须以某种方式了解任何类型的连接。

我不了解SOA服务,但在我看来,如果您使用$_em->getRepository()->save($entity)$_em->persist($entity),则完全没有区别。另一方面,如果在存储库中使用flush,则最终可能会遇到比所需更多的查询,因为您的存储库现在已经了解了业务逻辑。

我认为有一种方法可以做到这一点" SOA方式",但我想它并没有在存储库中持久保存实体。