Doctrine2版本库是保存实体的好地方吗?
当我阅读有关存储库的文档时,通常是以“只读”方式处理实体和集合。
从来没有例子存储库有像insertUser(User $user)
或updateUser(User $user)
。
但是,在使用SOA时,服务不应该与实体pipe理器一起工作(是的,不是吗?),所以:
- 我的服务应该知道全局的EntityManager吗?
- 如果我的服务只知道使用的存储库(比方说,UserRepository和ArticleRepository)
从这两个问题,另一个问题,我的服务应该明确地persist()
和flush()
我的实体?
是的,存储库通常只用于查询。
这是我怎么做的。 服务层pipe理持久性。 控制器层知道服务层,但不知道模型对象如何被持久化,也不知道它们来自哪里。 对于控制器层关心的是要求服务层坚持并返回对象 – 它并不关心它是如何实际完成的。
服务层本身非常适合于了解持久层:实体或文档pipe理器,存储库等。
下面是一些代码,使其更清晰:
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); } }
如果您查看存储库模式http://martinfowler.com/eaaCatalog/repository.html ,
据说存储库使用“集合式界面”。
之后,它也写成“对象可以从存储库中添加和删除,就像他们可以从一个简单的对象集合中获得的一样”。
我并不是说这是一本圣经,但是从概念上看,没有什么问题可以看到你可以查询的集合。 但是,因为它是一个集合,所以可以添加,删除…实际上,ObjectRepository应该实现Doctrine \ Common \ Collection 🙂
另一方面,最重要的是不要搞乱读写,正如CQS所说。 这也许是为什么他们不直接这样做,以避免滥用和读/写混合。
编辑:我应该谈论flush
。 这不应该在存储库本身,因为它可能会破坏事务一致性。
你最好把flush
调用转换成包装整个业务事务逻辑的东西(一个处理命令的命令总线?)
那么,如何在不使用entityManager的情况下获取仓库? 毕竟,如果没有连接到数据库,这些实体不会被神奇地保存起来,所以你的服务必须以某种方式意识到任何types的连接。
我不知道SOA服务,但是在我看来,如果使用$_em->getRepository()->save($entity)
或$_em->persist($entity)
,则完全没有区别。 另一方面,如果在存储库中使用flush,那么当存储库现在知道业务逻辑时,最终可能会产生比所需更多的查询。
我认为有一种方法可以做到这一点“SOA的方式”,但我想这不是坚持存储库中的实体。