在某个控制器中,我需要在数据库中进行几次插入/更新。为此,我使用了 4 个实体的 4 个存储库,但我需要在工作单元中完成此操作。
我知道我可以直接在控制器上进行这些插入/更新,并使用$em->getConnection()->beginTransaction()
、$em->getConnection()->rollBack()
和$em->getConnection()->commit()
来确保全部完成或全部完成。但这违背了symfony的最佳实践,所以我想使用存储库。
我已经看过这个关于原则 1 的教程,但它似乎是一个非常复杂的解决方案,应该更简单。
知道吗?
提前谢谢你。
编辑,我正在使用Symfony 3.3.5。
edit2,我添加了一个我想做的事情的例子。整个过程是将员工写的消息添加到公司内的其他部门同事。邮件可能有也可能没有附件(假设有附件(。这些文件应显示为部门和公司文件,以便即使删除了部门,这些文件仍继续显示为属于公司。
我没有在代码中包含错误处理以使其更简单。
// New Files
$file1 = new File(); // AppBundleEntityFile
$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(); // AppBundleEntityPost
$post->setContent($some_text)
->setAuthor($some_user) // AppBundleEntityUser
->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(); // AppBundleEntityNotification
$notif->setText("Text")
->setPost($post)
->addAddressee($some_dept_member)
->addAddressee($other_dept_member);
$notif = $em->getRepository('AppBundle:Notification')->insert($notif);
在存储库中,应仅使用 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) ;