在某个控制器中,我需要在数据库中进行多次插入/更新。我正在使用4个实体的4个存储库,但我需要在一个工作单元中完成。
我知道我可以直接在控制器上执行这些插入/更新,并使用$em->getConnection()->beginTransaction()
,$em->getConnection()->rollBack()
和$em->getConnection()->commit()
来确保完成所有操作或不执行任何操作。但这违反了symfony最佳实践,因此我想使用存储库。
我已经看到了this tutorial的Doctrine 1,但它似乎是一个非常复杂的解决方案,应该更简单。
有什么想法吗?
提前谢谢。
编辑,我正在使用Symfony 3.3.5。
edit2,我添加了一个我想做的例子。整个过程是将一个工人写的消息添加到公司内部的其他部门伙伴。该消息可能有也可能没有附件(让我们说它有)。这些文件应显示为部门和公司文件,这样即使删除了部门,文件也会继续显示为属于公司。
我没有在代码中包含错误处理以使其更简单。
// New Files
$file1 = new File(); // AppBundle\Entity\File
$file1->setName("name1");
$file2 = new File();
$file2->setName("name2");
$em->getRepository('AppBundle:File')->insert($file1);
$em->getRepository('AppBundle:File')->insert($file2);
// New Post
$post = new Post(); // AppBundle\Entity\Post
$post->setContent($some_text)
->setAuthor($some_user) // AppBundle\Entity\User
->addFile($file1)
->addFile($file2);
$em->getRepository('AppBundle:Post')->insert($post);
// Getting company and department
$company = $em->getRepository('AppBundle:Company')->findOneByCode($some_company_code);
$department = $em->getRepository('AppBundle:Department')->findOneByCode($some_dept_code);
$company->addFile($file1)->addFile($file2);
$department->addFile($file1)->addFile($file2);
$em->getRepository('AppBundle:Company')->update($company);
$em->getRepository('AppBundle:Department')->update($department);
// Notifications
$notif = new Notification(); // AppBundle\Entity\Notification
$notif->setText("Text")
->setPost($post)
->addAddressee($some_dept_member)
->addAddressee($other_dept_member);
$notif = $em->getRepository('AppBundle:Notification')->insert($notif);
答案 0 :(得分:0)
在存储库中,您应该仅使用DQL获取实体或执行查询以检索某些数据。
每次需要在数据库中创建新行时,都必须通知实体管理器您要保留实体,并调用$em->persist($myNewEntity)
。这告知实体管理器该实体应该保持为dB。
创建(并保留)所有实体和/或修改获取的实体后,您只需调用$em->persist()
一次:实体管理器将在单个事务中执行所有必需的插入/更新/删除操作到你的dB。
如果您还需要在同一事务中检索/获取数据,您应该考虑将所有代码包含在回调函数中并将其传递给实体管理器,如下所示
$myCallback=function($em) {
//Do all here: access repositories, create new entities, edit entities
//...
//no need to call $em->flush(), it will be called by Doctrine after the execution of the callback
};
$em->transactional($myCallback) ;