61

当我阅读有关存储库的文档时,通常以“只读”方式使用实体和集合。

从来没有示例存储库具有类似insertUser(User $user)or的方法updateUser(User $user)

但是,在使用 SOA 时,Service 不应该与 Entity Manager 一起使用(没错,不是吗?)所以:

  1. 我的服务应该知道全局 EntityManager 吗?
  2. 我的服务是否应该只知道使用的存储库(比如说,UserRepository 和 ArticleRepository)

从这两个问题,另一个问题,我的服务是否应该明确persist()flush()我的实体?

4

3 回答 3

48

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

这是我的做法。服务层管理持久性。控制器层知道服务层,但不知道模型对象是如何持久化的,也不知道它们来自哪里。控制器层关心的是要求服务层持久化并返回对象——它并不关心它实际上是如何完成的。

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

这里有一些代码让它更清楚:

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);
    }
}
于 2011-12-03T19:42:50.567 回答
9

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

据说存储库使用“类似集合的界面”。

后来,它还写了“对象可以添加到存储库中,也可以从存储库中删除,就像它们可以从简单的对象集合中一样”。

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

另一方面,最重要的是不要像 CQS 所说的那样搞乱读写。这可能是他们不允许直接这样做的原因,以避免滥用和读/写混合。

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

You'd better move the flush call to something that wraps the whole business transaction logic (a command bus handling a command f.e?)

于 2014-01-16T07:21:13.420 回答
2

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

我不了解 SOA 服务,但在我看来,如果您使用$_em->getRepository()->save($entity)$_em->persist($entity). 另一方面,如果您在存储库中使用刷新,您可能会得到比需要更多的查询,因为您的存储库现在知道业务逻辑。

我认为有一种方法可以做到这一点“SOA 方式”,但我想它不会将实体保留在存储库中。

于 2011-12-03T19:42:22.967 回答